Skip to content

Commit

Permalink
Update "revision" to "version" to maintain consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
jared-cannon committed Jan 12, 2025
1 parent 2f3b855 commit 6af7f9e
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 128 deletions.
21 changes: 13 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Imagine you have a Post model and want to track how the title and body evolve ov
```php
use AvocetShores\LaravelRewind\Facades\Rewind;

// Update the post, creating a new revision
// Update the post, creating a new version
$post->title = 'Updated Title';
$post->save();

Expand All @@ -22,18 +22,23 @@ Rewind::undo($post);

// Need that change back?
Rewind::redo($post);
```

// Or jump directly to a specific version
Rewind::goToVersion($post, 5);
You can also view a list of previous versions of a model, see what changed, and even jump to a specific version.

```php
$versions = $post->versions;

Rewind::goToVersion($post, $versions->first()->id);
```

## Features

- Track all or specific attributes on any of your models.
- Automatically log old and new values in a dedicated “rewind_revisions” table.
- Automatically log old and new values in a dedicated “rewind_versions” table.
- Easily undo or redo changes.
- Optionally store your model’s current version for full undo/redo capabilities.
- Access a revision audit log for each model to see every recorded version.
- Access a version audit log for each model to see every recorded version.

## Installation

Expand All @@ -58,7 +63,7 @@ php artisan vendor:publish --tag="laravel-rewind-config"

## Getting Started

To enable revision tracking on a model:
To enable version tracking on a model:

### 1. Add the Rewindable trait to your Eloquent model:

Expand Down Expand Up @@ -93,7 +98,7 @@ php artisan rewind:add-version
- Once this column is in place, the RewindManager will automatically manage your model’s current_version, allowing
proper undo/redo flows.

That’s it! Now your model’s changes are recorded in the `rewind_revisions` table, and you can jump backwards or forwards in time.
That’s it! Now your model’s changes are recorded in the `rewind_versions` table, and you can jump backwards or forwards in time.

## Usage

Expand All @@ -103,7 +108,7 @@ That’s it! Now your model’s changes are recorded in the `rewind_revisions` t
$post = Post::find(1);
$post->title = "New Title";
$post->save();
// A new revision is automatically created
// A new version is automatically created
```

2. Undoing / Redoing with the Rewind Facade
Expand Down
26 changes: 13 additions & 13 deletions config/rewind.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
|--------------------------------------------------------------------------
|
| By default, we will not store rewinds events (e.g. undo or redo) in the
| revisions table. If you would like to store these events, you may
| versions table. If you would like to store these events, you may
| enable this option. This can be overridden on a per-model basis using
| the shouldRecordRewinds method.
*/
Expand All @@ -18,20 +18,20 @@

/*
|--------------------------------------------------------------------------
| Rewind Revisions Table Name
| Rewind Versions Table Name
|--------------------------------------------------------------------------
|
| Here you may define the name of the table that stores the revisions.
| By default, it is set to "rewind_revisions". You may override it
| Here you may define the name of the table that stores the versions.
| By default, it is set to "rewind_versions". You may override it
| via an environment variable or update this value directly.
|
*/

'table_name' => env('LARAVEL_REWIND_TABLE', 'rewind_revisions'),
'table_name' => env('LARAVEL_REWIND_TABLE', 'rewind_versions'),

/*
|--------------------------------------------------------------------------
| Rewind Revisions Table User ID Column
| Rewind Versions Table User ID Column
|--------------------------------------------------------------------------
|
| Here you may define the name of the column that stores the user ID.
Expand All @@ -57,23 +57,23 @@

/*
|--------------------------------------------------------------------------
| Rewind Revisions Table Model
| Rewind Versions Table Model
|--------------------------------------------------------------------------
|
| Here you may define the model that represents the revisions table.
| By default, it is set to "AvocetShores\LaravelRewind\Models\RewindRevision".
| Here you may define the model that represents the versions table.
| By default, it is set to "AvocetShores\LaravelRewind\Models\RewindVersion".
| You may override it via an environment variable or update this value directly.
|
*/

'rewind_revision_model' => env('LARAVEL_REWIND_REVISION_MODEL', AvocetShores\LaravelRewind\Models\RewindRevision::class),
'rewind_version_model' => env('LARAVEL_REWIND_VERSION_MODEL', AvocetShores\LaravelRewind\Models\RewindVersion::class),

/*
|--------------------------------------------------------------------------
| Rewind Revisions Table Connection
| Rewind Versions Table Connection
|--------------------------------------------------------------------------
|
| Here you may define the connection that the revisions table uses.
| Here you may define the connection that the versions table uses.
| By default, it is set to "null" which uses the default connection.
| You may override it via an environment variable or update this value directly.
|
Expand All @@ -87,7 +87,7 @@
|--------------------------------------------------------------------------
|
| If true, the package will automatically store the currently authenticated
| user's ID in the revisions table (when available). If your application
| user's ID in the versions table (when available). If your application
| doesn't track or need user IDs, set this value to false.
|
*/
Expand Down
18 changes: 4 additions & 14 deletions src/LaravelRewindServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use AvocetShores\LaravelRewind\Commands\AddVersionTrackingColumnCommand;
use AvocetShores\LaravelRewind\Exceptions\InvalidConfigurationException;
use AvocetShores\LaravelRewind\Models\RewindRevision;
use AvocetShores\LaravelRewind\Models\RewindVersion;
use AvocetShores\LaravelRewind\Services\RewindManager;
use Illuminate\Database\Eloquent\Model;
use Spatie\LaravelPackageTools\Package;
Expand All @@ -22,7 +22,7 @@ public function configurePackage(Package $package): void
$package
->name('laravel-rewind')
->hasConfigFile()
->hasMigration('create_rewind_revisions_table')
->hasMigration('create_rewind_versions_table')
->hasCommand(AddVersionTrackingColumnCommand::class);
}

Expand All @@ -36,24 +36,14 @@ public function registeringPackage(): void
/**
* @throws InvalidConfigurationException
*/
public static function determineRewindRevisionModel(): string
public static function determineRewindVersionModel(): string
{
$rewindModel = config('laravel-rewind.rewind_revision_model') ?? RewindRevision::class;
$rewindModel = config('laravel-rewind.rewind_version_model') ?? RewindVersion::class;

if (! is_a($rewindModel, Model::class, true)) {
throw InvalidConfigurationException::modelIsNotValid($rewindModel);
}

return $rewindModel;
}

/**
* @throws InvalidConfigurationException
*/
public static function getRewindRevisionModelInstance(): Model
{
$rewindModel = static::determineRewindRevisionModel();

return new $rewindModel;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class RewindRevision extends Model
class RewindVersion extends Model
{
/**
* Dynamically set the table name from config in the constructor.
Expand Down
58 changes: 29 additions & 29 deletions src/Services/RewindManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ public function undo(Model $model): bool
}

// Find the previous version
$previousRevision = $model->revisions()
$previousVersion = $model->versions()

Check failure on line 34 in src/Services/RewindManager.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Illuminate\Database\Eloquent\Model::versions().
->where('version', '<', $currentVersion)
->orderBy('version', 'desc')
->first();

if (! $previousRevision) {
if (! $previousVersion) {
return false;
}

// Apply the revision for the previous version
return $this->applyRevision($model, $previousRevision->version);
// Apply the version for the previous version
return $this->applyVersion($model, $previousVersion->version);
}

/**
Expand All @@ -57,17 +57,17 @@ public function redo(Model $model): bool
$currentVersion = $this->determineCurrentVersion($model);

// Find the next higher version
$nextRevision = $model->revisions()
$nextVersion = $model->versions()

Check failure on line 60 in src/Services/RewindManager.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Illuminate\Database\Eloquent\Model::versions().
->where('version', '>', $currentVersion)
->orderBy('version', 'asc')
->first();

if (! $nextRevision) {
if (! $nextVersion) {
return false;
}

// Apply the next revision
return $this->applyRevision($model, $nextRevision->version);
// Apply the next version
return $this->applyVersion($model, $nextVersion->version);
}

/**
Expand All @@ -80,64 +80,64 @@ public function goToVersion(Model $model, int $version): bool
$this->assertRewindable($model);

// Validate the target version
$revision = $model->revisions()->where('version', $version)->first();
if (! $revision) {
$version = $model->versions()->where('version', $version)->first();

Check failure on line 83 in src/Services/RewindManager.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Illuminate\Database\Eloquent\Model::versions().
if (! $version) {
throw new VersionDoesNotExistException('The specified version does not exist.');
}

// Apply the revision
return $this->applyRevision($model, $version);
// Apply the version
return $this->applyVersion($model, $version);
}

/**
* Core function to apply the state of a revision to the model.
* Optionally create a new revision if config or the model says so.
* Core function to apply the state of a version to the model.
* Optionally create a new version if config or the model says so.
*
* @throws LaravelRewindException
*/
protected function applyRevision(Model $model, int $targetVersion): bool
protected function applyVersion(Model $model, int $targetVersion): bool
{
// First, make sure the model implements the Rewindable trait
$this->assertRewindable($model);

$revisionToApply = $model->revisions()->where('version', $targetVersion)->first();
if (! $revisionToApply) {
$versionToApply = $model->versions()->where('version', $targetVersion)->first();

Check failure on line 103 in src/Services/RewindManager.php

View workflow job for this annotation

GitHub Actions / phpstan

Call to an undefined method Illuminate\Database\Eloquent\Model::versions().
if (! $versionToApply) {
throw new VersionDoesNotExistException('The specified version does not exist.');
}

// Prepare the new_values to be applied to the model
$attributes = $revisionToApply->new_values ?: [];
$attributes = $versionToApply->new_values ?: [];

// Determine if we want to log a new revision for this revert/redo action
// Determine if we want to log a new version for this revert/redo action
$shouldRecordRewind = config('laravel-rewind.record_rewinds', false)
|| (method_exists($model, 'shouldRecordRewinds') && $model->shouldRecordRewinds());

// Capture the model's current state so we can store it as old_values if we create a revision
// Capture the model's current state so we can store it as old_values if we create a version
$previousModelState = $model->attributesToArray();

DB::transaction(function () use ($model, $attributes, $shouldRecordRewind, $previousModelState, $revisionToApply) {
DB::transaction(function () use ($model, $attributes, $shouldRecordRewind, $previousModelState, $versionToApply) {
// Temporarily disable normal Rewindable event handling
$model->disableRewindEvents = true;

Check failure on line 120 in src/Services/RewindManager.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property Illuminate\Database\Eloquent\Model::$disableRewindEvents.

// Update the model’s attributes to the "target" revision state
// Update the model’s attributes to the "target" version state
foreach ($attributes as $key => $value) {
$model->setAttribute($key, $value);
}

// Save the new current_version if the model has the column
if ($this->modelHasCurrentVersionColumn($model)) {
$model->current_version = $revisionToApply->version;
$model->current_version = $versionToApply->version;

Check failure on line 129 in src/Services/RewindManager.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property Illuminate\Database\Eloquent\Model::$current_version.
}

$model->save();

// Re-enable normal event handling
$model->disableRewindEvents = false;

// If desired, create a new revision capturing the revert/redo event
// If desired, create a new version capturing the revert/redo event
if ($shouldRecordRewind) {
$rewindModelClass = LaravelRewindServiceProvider::determineRewindRevisionModel();
$nextVersion = ($model->revisions()->max('version') ?? 0) + 1;
$rewindModelClass = LaravelRewindServiceProvider::determineRewindVersionModel();
$nextVersion = ($model->versions()->max('version') ?? 0) + 1;

$rewindModelClass::create([
'model_type' => get_class($model),
Expand Down Expand Up @@ -167,7 +167,7 @@ protected function applyRevision(Model $model, int $targetVersion): bool
* Determine the model's current version.
*
* If a current_version column exists, return it.
* Otherwise, fallback to the highest version from the revisions table (a best guess).
* Otherwise, fallback to the highest version from the versions table (a best guess).
*/
protected function determineCurrentVersion(Model $model): int
{
Expand All @@ -176,8 +176,8 @@ protected function determineCurrentVersion(Model $model): int
return $model->current_version ?? 0;
}

// If there's no current_version column, fallback to the highest known revision
return $model->revisions()->max('version') ?? 0;
// If there's no current_version column, fallback to the highest known version
return $model->versions()->max('version') ?? 0;
}

/**
Expand Down
Loading

0 comments on commit 6af7f9e

Please sign in to comment.