Skip to content

Commit

Permalink
Refactor package to using Enum for workflow which can be extended/use…
Browse files Browse the repository at this point in the history
…d in the consumer applications
  • Loading branch information
Kurt Friars committed Mar 15, 2024
1 parent 337b7c2 commit a301b14
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 50 deletions.
3 changes: 3 additions & 0 deletions config/publisher.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?php

use Plank\Publisher\Enums\Status;

return [
'workflow' => Status::class,
'columns' => [
'draft' => 'draft',
'workflow' => 'status',
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/PublisherMigrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected function getMigrationContent(Model&Publishable $model)
$hasBeenPublishedColumn = config()->get('publisher.columns.has_been_published', 'has_been_published');
$draftColumn = config()->get('publisher.columns.draft', 'draft');
$workflowColumn = config()->get('publisher.columns.workflow', 'status');
$unpublishedState = $model->unpublishedState();
$unpublishedState = $model::workflow()::unpublished()->value;

return <<<EOT
<?php
Expand Down
18 changes: 0 additions & 18 deletions src/Concerns/HasPublishableAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,6 @@
*/
trait HasPublishableAttributes
{
public function initializeHasPublishableAttributes()
{
$this->mergeCasts([
$this->draftColumn() => 'json',
$this->hasBeenPublishedColumn() => 'boolean',
]);

$this->makeHidden($this->draftColumn());

$this->attributes[$this->hasBeenPublishedColumn()] ??= false;
}

public function draftColumn(): string
{
return config('publisher.columns.draft', 'draft');
}

public static function bootHasPublishableAttributes()
{
static::retrieved(function (Publishable&Model $model) {
Expand All @@ -44,7 +27,6 @@ public static function bootHasPublishableAttributes()

static::drafting(function (Publishable&Model $model) {
$model->putAttributesInDraft();
$model->{$model->workflowColumn()} = $model->unpublishedState();
});

static::drafted(function (Publishable&Model $model) {
Expand Down
51 changes: 35 additions & 16 deletions src/Concerns/IsPublishable.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Illuminate\Database\Eloquent\Model;
use Plank\Publisher\Builders\PublisherBuilder;
use Plank\Publisher\Contracts\Publishable;
use Plank\Publisher\Contracts\PublishingStatus;
use Plank\Publisher\Enums\Status;
use Plank\Publisher\Facades\Publisher;
use Plank\Publisher\Scopes\PublisherScope;

Expand All @@ -20,7 +22,21 @@ trait IsPublishable

public function initializeIsPublishable()
{
$this->attributes[$this->workflowColumn()] ??= $this->unpublishedState();
$this->mergePublishableCasts();

$this->{$this->workflowColumn()} ??= static::workflow()::unpublished();
$this->{$this->hasBeenPublishedColumn()} ??= false;

$this->makeHidden($this->draftColumn());
}

protected function mergePublishableCasts(): void
{
$this->mergeCasts([
$this->workflowColumn() => Status::class,
$this->draftColumn() => 'json',
$this->hasBeenPublishedColumn() => 'boolean',
]);
}

public static function bootIsPublishable()
Expand Down Expand Up @@ -80,6 +96,11 @@ public static function bootIsPublishable()
});
}

public function draftColumn(): string
{
return config('publisher.columns.draft', 'draft');
}

public function workflowColumn(): string
{
return config()->get('publisher.columns.workflow', 'status');
Expand All @@ -90,14 +111,12 @@ public function hasBeenPublishedColumn(): string
return config()->get('publisher.columns.has_been_published', 'has_been_published');
}

public function publishedState(): string
{
return 'published';
}

public function unpublishedState(): string
/**
* @return class-string<PublishingStatus>
*/
public static function workflow(): string
{
return 'draft';
return config()->get('publisher.workflow');
}

public static function query(): PublisherBuilder
Expand All @@ -112,24 +131,24 @@ public function newEloquentBuilder($query): PublisherBuilder

public function shouldBeDrafted(): bool
{
return $this->attributes[$this->workflowColumn()] !== $this->publishedState();
return $this->{$this->workflowColumn()} !== static::workflow()::published();
}

public function isBeingPublished(): bool
{
return $this->isDirty($this->workflowColumn())
&& $this->attributes[$this->workflowColumn()] === $this->publishedState();
&& $this->{$this->workflowColumn()} === static::workflow()::published();
}

public function isBeingUnpublished(): bool
{
return $this->isDirty($this->workflowColumn())
&& $this->attributes[$this->workflowColumn()] !== $this->publishedState();
&& $this->{$this->workflowColumn()} !== static::workflow()::published();
}

public function isPublished(): bool
{
return $this->attributes[$this->workflowColumn()] === $this->publishedState();
return $this->{$this->workflowColumn()} === static::workflow()::published();
}

public function isNotPublished(): bool
Expand All @@ -140,23 +159,23 @@ public function isNotPublished(): bool
public function wasPublished(): bool
{
return ($this->wasChanged($this->workflowColumn()) || $this->wasRecentlyCreated)
&& $this->{$this->workflowColumn()} === $this->publishedState();
&& $this->{$this->workflowColumn()} === static::workflow()::published();
}

public function wasUnpublished(): bool
{
return ($this->wasChanged($this->workflowColumn()) || $this->wasRecentlyCreated)
&& $this->{$this->workflowColumn()} !== $this->publishedState();
&& $this->{$this->workflowColumn()} !== static::workflow()::published();
}

public function wasDrafted(): bool
{
return $this->attributes[$this->workflowColumn()] !== $this->publishedState();
return $this->{$this->workflowColumn()} !== static::workflow()::published();
}

public function wasUndrafted(): bool
{
return $this->attributes[$this->workflowColumn()] === $this->publishedState();
return $this->{$this->workflowColumn()} === static::workflow()::published();
}

public function hasEverBeenPublished(): bool
Expand Down
6 changes: 3 additions & 3 deletions src/Concerns/QueriesPublishableModels.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function onlyPublished(): Builder&PublisherQueries
public function onlyDraft(): Builder&PublisherQueries
{
return $this->withoutGlobalScope(PublisherScope::class)
->whereNot($this->model->workflowColumn(), $this->model->publishedState());
->whereNot($this->model->workflowColumn(), $this->model::workflow()::published());
}

public function where($column, $operator = null, $value = null, $boolean = 'and')
Expand All @@ -53,13 +53,13 @@ protected function draftAllowedQuery($query, $column, $operator = null, $value =

protected function publishedWhere($query, $column, $operator = null, $value = null)
{
return $query->where($this->model->workflowColumn(), $this->model->publishedState())
return $query->where($this->model->workflowColumn(), $this->model::workflow()::published())
->where($column, $operator, $value, 'and');
}

protected function unpublishedWhere($query, $column, $operator = null, $value = null)
{
return $query->whereNot($this->model->workflowColumn(), $this->model->publishedState())
return $query->whereNot($this->model->workflowColumn(), $this->model::workflow()::published())
->where($this->model->draftColumn().'->'.$column, $operator, $value, 'and');
}

Expand Down
11 changes: 4 additions & 7 deletions src/Contracts/Publishable.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@ public function workflowColumn(): string;
public function hasBeenPublishedColumn(): string;

/**
* Get the value of the published state
* Get the Workflow State Enum
*
* @return class-string<PublishingStatus>
*/
public function publishedState(): string;

/**
* Get the value of the unpublished state
*/
public function unpublishedState(): string;
public static function workflow(): string;

/**
* Determine if the model should have its attributes stored in draft
Expand Down
10 changes: 10 additions & 0 deletions src/Contracts/PublishingStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Plank\Publisher\Contracts;

interface PublishingStatus
{
public static function published(): self;

public static function unpublished(): self;
}
21 changes: 21 additions & 0 deletions src/Enums/Status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Plank\Publisher\Enums;

use Plank\Publisher\Contracts\PublishingStatus;

enum Status: string implements PublishingStatus
{
case DRAFT = 'draft';
case PUBLISHED = 'published';

public static function published(): self
{
return self::PUBLISHED;
}

public static function unpublished(): self
{
return self::DRAFT;
}
}
5 changes: 3 additions & 2 deletions tests/Feature/MiddlewareTest.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<?php

use Illuminate\Support\Facades\Gate;
use Plank\Publisher\Enums\Status;
use Plank\Publisher\Tests\Helpers\Models\Post;
use Plank\Publisher\Tests\Helpers\Models\User;

use function Pest\Laravel\get;

beforeEach(function () {
$draft = Post::create([
$draft = Post::query()->create([
'author_id' => User::first()->id,
'title' => '(Published) My First Post',
'slug' => 'my-first-post',
'body' => 'A first post.',
'status' => 'published',
'status' => Status::PUBLISHED,
]);

$draft->title = '(Draft) My First Post';
Expand Down
7 changes: 4 additions & 3 deletions tests/Feature/PublishedTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

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

Expand Down Expand Up @@ -34,17 +35,17 @@
'title' => 'My First Post',
'slug' => 'my-first-post',
'body' => 'This is the body of my first post.',
'status' => 'published',
'status' => Status::published(),
]);

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

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

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

0 comments on commit a301b14

Please sign in to comment.