Skip to content

Commit

Permalink
Add method to revert draft changes on a model (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
kfriars authored Jan 15, 2025
1 parent 4410d42 commit 319460b
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/Concerns/IsPublishable.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
namespace Plank\Publisher\Concerns;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Plank\Publisher\Builders\PublisherBuilder;
use Plank\Publisher\Contracts\Publishable;
use Plank\Publisher\Contracts\PublishingStatus;
use Plank\Publisher\Enums\Status;
use Plank\Publisher\Exceptions\RevertException;
use Plank\Publisher\Facades\Publisher;
use Plank\Publisher\Scopes\PublisherScope;

Expand Down Expand Up @@ -102,6 +105,20 @@ public static function bootIsPublishable()
});
}

public function revert(): void
{
if (! $this->hasEverBeenPublished()) {
throw new RevertException('Publishable content cannot be reverted if it has never been published.');
}

DB::transaction(function () {
Publisher::withoutDraftContent(fn () => $this->refresh());
$this->{$this->draftColumn()} = null;
$this->{$this->workflowColumn()} = Status::published();
$this->save();
});
}

public function draftColumn(): string
{
return config('publisher.columns.draft', 'draft');
Expand Down
5 changes: 5 additions & 0 deletions src/Contracts/Publishable.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

interface Publishable extends PublishableAttributes, PublishableEvents
{
/**
* Drop all draft changes and restore the model as published
*/
public function revert(): void;

/**
* Get the name of the column that stores the draft attributes
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Exceptions/PublisherException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Plank\Publisher\Exceptions;

use Exception;

class PublisherException extends Exception {}
5 changes: 5 additions & 0 deletions src/Exceptions/RevertException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Plank\Publisher\Exceptions;

class RevertException extends PublisherException {}
3 changes: 3 additions & 0 deletions src/Facades/Publisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Plank\Publisher\Facades;

use Closure;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
Expand All @@ -16,6 +17,8 @@
* @method static bool draftContentRestricted()
* @method static void allowDraftContent()
* @method static void restrictDraftContent()
* @method static mixed withDraftContent(Closure $closure)
* @method static mixed withoutDraftContent(Closure $closure)
* @method static Collection<Model&Publishable> publishableModels()
*/
class Publisher extends Facade
Expand Down
21 changes: 21 additions & 0 deletions src/Services/PublisherService.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Plank\Publisher\Services;

use Closure;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -67,6 +68,26 @@ public function restrictDraftContent(): void
$this->draftContentAllowed = false;
}

public function withDraftContent(Closure $closure): mixed
{
$scope = $this->draftContentAllowed;
$this->draftContentAllowed = true;
$result = $closure();
$this->draftContentAllowed = $scope;

return $result;
}

public function withoutDraftContent(Closure $closure): mixed
{
$scope = $this->draftContentAllowed;
$this->draftContentAllowed = false;
$result = $closure();
$this->draftContentAllowed = $scope;

return $result;
}

/**
* @return Collection<Model&Publishable>
*/
Expand Down
46 changes: 46 additions & 0 deletions tests/Feature/PublishedTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Plank\Publisher\Enums\Status;
use Plank\Publisher\Exceptions\RevertException;
use Plank\Publisher\Tests\Helpers\Models\Post;
use Plank\Publisher\Tests\Helpers\Models\User;

Expand Down Expand Up @@ -49,3 +50,48 @@
$this->assertEquals(Status::unpublished(), $post->status);
$this->assertTrue($post->hasEverBeenPublished());
});

it('allows revert for content that has been published', function () {
/** @var Post $post */
$post = Post::create([
'author_id' => User::first()->id,
'title' => 'My First Post',
'slug' => 'my-first-post',
'body' => 'This is the body of my first post.',
'status' => Status::published(),
]);

$this->assertEquals(Status::published(), $post->status);
$this->assertTrue($post->hasEverBeenPublished());

$post->update([
'status' => 'draft',
]);

$post->update([
'title' => 'My Updated Post',
]);

$this->assertEquals(Status::unpublished(), $post->status);
$this->assertTrue($post->hasEverBeenPublished());

$post->revert();

$this->assertEquals(Status::published(), $post->status);
$this->assertNull($post->draft);
$this->assertEquals('My First Post', $post->title);
});

it('does nothing for revert when content has never been published', function () {
/** @var Post $post */
$post = Post::create([
'author_id' => User::first()->id,
'title' => 'My First Post',
'slug' => 'my-first-post',
'body' => 'This is the body of my first post.',
'status' => Status::unpublished(),
]);

$this->assertFalse($post->hasEverBeenPublished());
$post->revert();
})->throws(RevertException::class);

0 comments on commit 319460b

Please sign in to comment.