PHPackages                             eribloo/laravel-model-snapshots - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. eribloo/laravel-model-snapshots

ActiveLibrary

eribloo/laravel-model-snapshots
===============================

Laravel package for storing model versions

v0.4.3(1y ago)32.5k1[4 PRs](https://github.com/EriBloo/laravel-model-snapshots/pulls)MITPHPPHP ^8.1CI passing

Since Mar 12Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/EriBloo/laravel-model-snapshots)[ Packagist](https://packagist.org/packages/eribloo/laravel-model-snapshots)[ Docs](https://github.com/eribloo/laravel-model-snapshots)[ RSS](/packages/eribloo-laravel-model-snapshots/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (7)Dependencies (14)Versions (11)Used By (0)

Laravel package for storing model versions
==========================================

[](#laravel-package-for-storing-model-versions)

[![Latest Version on Packagist](https://camo.githubusercontent.com/f45adc417c3d3758abcad237845266ef07d18e4f25bc836c6f46c67d1a82b677/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f657269626c6f6f2f6c61726176656c2d6d6f64656c2d736e617073686f74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/eribloo/laravel-model-snapshots)[![GitHub Tests Action Status](https://camo.githubusercontent.com/149e9223bb21df9cf6ee74dc5964e7df16ea7f4db5cdb835cf203824a2dfebe1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f657269626c6f6f2f6c61726176656c2d6d6f64656c2d736e617073686f74732f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/eribloo/laravel-model-snapshots/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/da2b523544fe488baf6856fe3335ff33afd123e4067784e228751740845c5fbe/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f657269626c6f6f2f6c61726176656c2d6d6f64656c2d736e617073686f74732f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/eribloo/laravel-model-snapshots/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/ef21dc887fcd35cc1a59ad59cdd80ba333b4ad363beadcef106eaceff11d8795/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f657269626c6f6f2f6c61726176656c2d6d6f64656c2d736e617073686f74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/eribloo/laravel-model-snapshots)

> ⚠️ ***Disclaimer***
>
> This package is still under development and may change often.

Introduction
------------

[](#introduction)

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.

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Examples](#examples)
- [Usage](#usage)
    - [Basics](#basics)
        - [Creating snapshots](#creating-snapshots)
        - [Reverting, branching and forking snapshots](#reverting-branching-and-forking-snapshots)
        - [Relations](#relations)
    - [Configuring](#configuring)
        - [Snapshot Options](#snapshot-options)
        - [Versionist](#versionist)
    - [Traits](#traits)
    - [Events](#events)
- [Testing](#testing)
- [Changelog](#changelog)
- [Licence](#license)

Installation
------------

[](#installation)

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,

];
```

Usage
-----

[](#usage)

### Basics

[](#basics)

#### Creating snapshots

[](#creating-snapshots)

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:

- set version with Versionist class defined in config
- snapshot all attributes, excluding primary key, timestamps and hidden
- it won't create snapshot if other snapshot with the same stored attributes already exists - in such situation matching snapshot will be returned

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.

#### Reverting, branching and forking snapshots

[](#reverting-branching-and-forking-snapshots)

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 deleted
- `branch()` - creates new model from snapshotted version and duplicates all snapshots up to, and including, the one used, associating them with new model
- `fork()` - creates new model from snapshotted version with no snapshots history

Attributes excluded from snapshotting will be filled with current model values.

#### Relations

[](#relations)

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](#traits).

### Configuring

[](#configuring)

#### Snapshot options

[](#snapshot-options)

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](#versionist) used
- `snapshotExcept(array $exclude)` - exclude attributes from being stored
- `snapshotHidden(bool $option = true)` - store hidden attributes
- `snapshotDuplicate(bool $option = true)` - force snapshot even if the same already exists

Most 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 needed
- `description(?string)` - add optional short description
- `setExcept(array $except)`, `appendExcept(array $except)`, `removeExcept(array $except)` - modify excluded attributes list
- `withHidden()`, `withoutHidden()` - modify if hidden attributes should be snapshotted
- `forceDuplicate()`, `noDuplicate()` - if snapshot should be forced even if duplicate already exists

#### Versionist

[](#versionist)

Versionist is a class responsible for determining next snapshot version. There are 2 classes available by default:

- `IncrementingVersionist` - increments versions
- `SemanticVersionist` - keeps versions in `major.minor` format

If 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;
```

### Traits

[](#traits)

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 version
    - `getSnapshotByDate(DateTimeImmutable $date)` - returns last snapshot created before date
- `HasSnapshotRelations` - provides relationship methods for creating connections with snapshots:
    - `morphSnapshots(string $snapshotClass)` - helper `morphToMany`
    - `morphSnapshot(string $snapshotClass)` - helper `morphToOne`
    - `morphSnapshotAsModels(string $snapshotClass)` - `morphToMany` that returns snapshots with `toModels(false)`applied
    - `morphSnapshotAsModel(string $snapshotClass)` - `morphToOne` that returns snapshot with `toModel(false)`applied

### Events

[](#events)

There are a few events that get dispatched:

- `SnapshotCommitted` - dispatched when new snapshot is committed, but not when duplicate is found
- `SnapshotReverted` - dispatched when snapshot is reverted
- `SnapshotBranched` - dispatched when new snapshot branch is created
- `SnapshotForked` - dispatched when snapshot is forked

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance67

Regular maintenance activity

Popularity20

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~113 days

Recently: every ~134 days

Total

6

Last Release

589d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/72dd6cdd926e56d3f5372c97f485a719ddc38d8cffcb681f593be7d634da81fd?d=identicon)[eribloo](/maintainers/eribloo)

---

Top Contributors

[![EriBloo](https://avatars.githubusercontent.com/u/19932449?v=4)](https://github.com/EriBloo "EriBloo (100 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (13 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (9 commits)")[![it-can](https://avatars.githubusercontent.com/u/644288?v=4)](https://github.com/it-can "it-can (1 commits)")

---

Tags

history-trackinglaravelmodelphpsnapshotlaravelsnapshotmodelhistoryversionEriBloolaravel-model-snapshots

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/eribloo-laravel-model-snapshots/health.svg)

```
[![Health](https://phpackages.com/badges/eribloo-laravel-model-snapshots/health.svg)](https://phpackages.com/packages/eribloo-laravel-model-snapshots)
```

###  Alternatives

[mpociot/versionable

Allows to create Laravel 4 / 5 / 6 / 7 / 8 / 9 / 10 / 11 Model versioning and restoring

7841.1M6](/packages/mpociot-versionable)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[spatie/laravel-prometheus

Export Laravel metrics to Prometheus

2651.3M6](/packages/spatie-laravel-prometheus)[lacodix/laravel-model-filter

A Laravel package to filter, search and sort models with ease while fetching from database.

17649.9k](/packages/lacodix-laravel-model-filter)[ralphjsmit/laravel-helpers

A package containing handy helpers for your Laravel-application.

13704.6k2](/packages/ralphjsmit-laravel-helpers)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
