---
title: Versioning
---

# Versioning

<div class="documentation__toc"></div>

## Getting Started

### Enable Versioning

Versioning entry models is as easy as enabling it on your model using the `$versionable` property:

```php
protected $versionable = true;
```

You can also define the stream as versionable in it's migration:

```php
protected $stream = [
    'slug' => 'example',
    'versionable' => true,
];
```

Saving revisions and what was changed will occur automatically now!

## Versioning UI

<!-- @todo move this into UI when ready -->

### Defining Routes

To implement UI for versioning in your custom addon you must first enable versioning as needed above and then use the `VersionRouter` to easily define routes for viewing the versioning management.

To get started use the `VersionRouter` router to automate defining routes for the version management:

```php
\Anomaly\Streams\Platform\Version\VersionRouter::route(Addon $addon, $controller, $prefix = null, $base = '/versions');
```

The `$addon` is the instance of the addon that own's these routes. You can easily get this from your service provider (see example below).

The `$controller` is your **addon's controller** that extends the base `VersionsController`.

The `$prefix` is a path prefix that is helpful if the routes need to be prefixed for some reason. This is useful for example if you are allowing version management for multiple streams within a single addon. You can prefix each management area and use controllers for either stream this way.

Below is a trimmed down real-world example of the Pages module implementation:

```php
<?php namespace Anomaly\PagesModule;

use Anomaly\Streams\Platform\Addon\AddonServiceProvider;
use Anomaly\PagesModule\Http\Controller\Admin\VersionsController;
use Anomaly\Streams\Platform\Version\VersionRouter;

class PagesModuleServiceProvider extends AddonServiceProvider
{

    public function map(VersionRouter $versions)
    {
        $versions->route($this->addon, VersionsController::class);
    }
}
```

### Versions Controller

To create a versions controller simply extend the base `Anomaly\Streams\Platform\Http\Controller\VersionsController` controller with your own.

The only property that is required is the `$model` property which tells the controller which model to display versions for.

```php
<?php namespace Anomaly\PagesModule\Http\Controller\Admin;

use Anomaly\PagesModule\Page\PageModel;

class VersionsController extends \Anomaly\Streams\Platform\Http\Controller\VersionsController
{

   /**
     * The versionable model.
     *
     * @var string
     */
    protected $model = PageModel::class;

}
```

### Versions Button

By default versioning buttons will be added ot the default buttons for **form builders** when the stream is marked versionable as specified above. However you may want to customize them. You can do so by leveraging the registered `versions` button and appending it's definition from there.

For exmaple to open the versions UI in a new window:

```php
protected $buttons = [
    'versions' => [
        'target' => '_blank',
    ],
    'cancel',
    'view' => [
        'enabled' => 'edit',
        'target'  => '_blank',
    ],
];
```


## Basic Usage

### Temporarily Disabling Versioning

Should you need to temporarily disable versioning you can use the helper methods:

```php
$entry->enableVersioning();
$entry->disableVersioning();

if ($entry->versioningDisabled()) {
    // Versioning is disabled.
}
```

### Omitting Attributes From Versioning

To disable tracking of attributes from versioning you can use the `nonVersionedAttributes` property:

```php
protected $nonVersionedAttributes = [
    'remember_token',
    'reset_token',
    'password',
];
```

## Accessing Versions

Versions can be fetched off the model instance you want to get versions for:

```php
$current = $entry->getCurrentVersion();
$previous = $entry->getPreviousVersion();

foreach ($entry->getVersions() as $version) {
    $version->getVersion(); // The version ID
}
```

### Accessing Model Data/Snapshots

You can grab the snapshot instance of the old model off the version instance using the `model` property:

```php
$model = $version->getModel(); // Model Instance
```

You can grab only the data that was changed at that point with `getData`:

```php
$changes = $version->getData(); // array
```
