PHPackages                             overtrue/laravel-versionable - 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. [Database &amp; ORM](/categories/database)
4. /
5. overtrue/laravel-versionable

ActiveLibrary[Database &amp; ORM](/categories/database)

overtrue/laravel-versionable
============================

Make Laravel model versionable.

v6.0.0(1mo ago)585308.0k↓12.4%49[11 issues](https://github.com/overtrue/laravel-versionable/issues)5MITPHPPHP ^8.3CI failing

Since May 31Pushed 2mo ago10 watchersCompare

[ Source](https://github.com/overtrue/laravel-versionable)[ Packagist](https://packagist.org/packages/overtrue/laravel-versionable)[ GitHub Sponsors](https://github.com/overtrue)[ RSS](/packages/overtrue-laravel-versionable/feed)WikiDiscussions 5.x Synced 1mo ago

READMEChangelog (10)Dependencies (16)Versions (64)Used By (5)

Laravel Versionable
===================

[](#laravel-versionable)

[![Build Status](https://github.com/overtrue/laravel-versionable/workflows/CI/badge.svg)](https://github.com/overtrue/laravel-versionable/actions)[![Latest Stable Version](https://camo.githubusercontent.com/6e3c8644234f363dbd7364d8f7b05380f7fea38f3dc5166fe15e44c366e53d03/68747470733a2f2f706f7365722e707567782e6f72672f6f766572747275652f6c61726176656c2d76657273696f6e61626c652f762f737461626c652e737667)](https://packagist.org/packages/overtrue/laravel-versionable)[![Latest Unstable Version](https://camo.githubusercontent.com/f299bd45ab3a4047d6b740a0ec78f3f8dd420e5bc4a2183575f0f349b096d6a7/68747470733a2f2f706f7365722e707567782e6f72672f6f766572747275652f6c61726176656c2d76657273696f6e61626c652f762f756e737461626c652e737667)](https://packagist.org/packages/overtrue/laravel-versionable)[![Total Downloads](https://camo.githubusercontent.com/3da1fd2f744b328259d53688659246cade0f70cb275f7deb3106b286cb13a388/68747470733a2f2f706f7365722e707567782e6f72672f6f766572747275652f6c61726176656c2d76657273696f6e61626c652f646f776e6c6f616473)](https://packagist.org/packages/overtrue/laravel-versionable)[![License](https://camo.githubusercontent.com/168c245b2b0e81c10043797ec4c14829bf4906cc305c8870306f87ef4d9a3a62/68747470733a2f2f706f7365722e707567782e6f72672f6f766572747275652f6c61726176656c2d76657273696f6e61626c652f6c6963656e7365)](https://packagist.org/packages/overtrue/laravel-versionable)

It's a minimalist way to make your model support version history, and it's very simple to revert to the specified version.

[![Sponsor me](https://github.com/overtrue/overtrue/raw/master/sponsor-me-button-s.svg?raw=true)](https://github.com/sponsors/overtrue)

Requirement
-----------

[](#requirement)

1. PHP &gt;= 8.1.0
2. laravel/framework &gt;= 9.0

Features
--------

[](#features)

- Keep the specified number of versions.
- Whitelist and blacklist for versionable attributes.
- Easily revert to the specified version.
- Record only changed attributes.
- Easy to customize.

Installing
----------

[](#installing)

```
composer require overtrue/laravel-versionable -vvv
```

First, publish the config file and migrations:

```
php artisan vendor:publish --provider="Overtrue\LaravelVersionable\ServiceProvider"
```

Then run this command to create a database migration:

```
php artisan migrate
```

Usage
-----

[](#usage)

Add `Overtrue\LaravelVersionable\Versionable` trait to the model and set versionable attributes:

```
use Overtrue\LaravelVersionable\Versionable;

class Post extends Model
{
    use Versionable;

    /**
     * Versionable attributes
     *
     * @var array
     */
    protected $versionable = ['title', 'content'];

    // Or use a blacklist
    //protected $dontVersionable = ['created_at', 'updated_at'];

}
```

Versions will be created on the vensionable model saved.

```
$post = Post::create(['title' => 'version1', 'content' => 'version1 content']);
$post->update(['title' => 'version2']);
```

### Get versions

[](#get-versions)

```
$post->versions; // all versions
$post->latestVersion; // latest version
// or
$post->lastVersion;

$post->versions->first(); // first version
// or
$post->firstVersion;

$post->versionAt('2022-10-06 12:00:00'); // get version from a specific time
// or
$post->versionAt(\Carbon\Carbon::create(2022, 10, 6, 12));
```

### Revert

[](#revert)

Revert a model instance to the specified version:

```
$post->getVersion(3)->revert();

// or

$post->revertToVersion(3);
```

#### Revert without saving

[](#revert-without-saving)

```
$version = $post->versions()->first();

$post = $version->revertWithoutSaving();
```

### Remove versions

[](#remove-versions)

```
// soft delete
$post->removeVersion($versionId = 1);
$post->removeVersions($versionIds = [1, 2, 3]);
$post->removeAllVersions();

// force delete
$post->forceRemoveVersion($versionId = 1);
$post->forceRemoveVersions($versionIds = [1, 2, 3]);
$post->forceRemoveAllVersions();
```

### Restore deleted version by id

[](#restore-deleted-version-by-id)

```
$post->restoreTrashedVersion($id);
```

### Temporarily disable versioning

[](#temporarily-disable-versioning)

```
// create
Post::withoutVersion(function () use (&$post) {
    Post::create(['title' => 'version1', 'content' => 'version1 content']);
});

// update
Post::withoutVersion(function () use ($post) {
    $post->update(['title' => 'updated']);
});
```

### Custom Version Store strategy

[](#custom-version-store-strategy)

You can set the following different version policies through property `protected $versionStrategy`:

- `Overtrue\LaravelVersionable\VersionStrategy::DIFF` - Version content will only contain changed attributes (default strategy).
- `Overtrue\LaravelVersionable\VersionStrategy::SNAPSHOT` - Version content will contain all versionable attribute values.

### Show diff between the two versions

[](#show-diff-between-the-two-versions)

```
$diff = $post->getVersion(1)->diff($post->getVersion(2));
```

`$diff` is a object `Overtrue\LaravelVersionable\Diff`, it based on [jfcherng/php-diff](https://github.com/jfcherng/php-diff).

You can render the diff to [many formats](https://github.com/jfcherng/php-diff#introduction), and all formats result will be like follows:

```
[
    $attribute1 => $diffOfAttribute1,
    $attribute2 => $diffOfAttribute2,
    ...
    $attributeN => $diffOfAttributeN,
]
```

#### toArray()

[](#toarray)

```
$diff->toArray();
//
[
    "name" => [
        "old" => "John",
        "new" => "Doe",
    ],
    "age" => [
        "old" => 25,
        "new" => 26,
    ],
]
```

### Other formats

[](#other-formats)

```
toArray(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toText(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toJsonText(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toContextText(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toInlineHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toJsonHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toSideBySideHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
```

> **Note**
>
> `$differOptions` and `$renderOptions` are optional, you can set them following the README of [jfcherng/php-diff](https://github.com/jfcherng/php-diff#example). `$stripTags` allows you to remove HTML tags from the Diff, helpful when you don't want to show tags.

### Using custom version model

[](#using-custom-version-model)

You can define `$versionModel` in a model, that used this trait to change the model(table) for versions

> **Note**
>
> Model MUST extend class `\Overtrue\LaravelVersionable\Version`;

```
