From a301b140e54a752d119a1d5d4e628f5146753cb2 Mon Sep 17 00:00:00 2001 From: Kurt Friars Date: Fri, 15 Mar 2024 13:35:44 -0400 Subject: [PATCH] Refactor package to using Enum for workflow which can be extended/used in the consumer applications --- config/publisher.php | 3 ++ src/Commands/PublisherMigrations.php | 2 +- src/Concerns/HasPublishableAttributes.php | 18 -------- src/Concerns/IsPublishable.php | 51 ++++++++++++++++------- src/Concerns/QueriesPublishableModels.php | 6 +-- src/Contracts/Publishable.php | 11 ++--- src/Contracts/PublishingStatus.php | 10 +++++ src/Enums/Status.php | 21 ++++++++++ tests/Feature/MiddlewareTest.php | 5 ++- tests/Feature/PublishedTest.php | 7 ++-- 10 files changed, 84 insertions(+), 50 deletions(-) create mode 100644 src/Contracts/PublishingStatus.php create mode 100644 src/Enums/Status.php diff --git a/config/publisher.php b/config/publisher.php index 391c209..af14bec 100644 --- a/config/publisher.php +++ b/config/publisher.php @@ -1,6 +1,9 @@ Status::class, 'columns' => [ 'draft' => 'draft', 'workflow' => 'status', diff --git a/src/Commands/PublisherMigrations.php b/src/Commands/PublisherMigrations.php index aca3719..3f0cd2f 100644 --- a/src/Commands/PublisherMigrations.php +++ b/src/Commands/PublisherMigrations.php @@ -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 <<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) { @@ -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) { diff --git a/src/Concerns/IsPublishable.php b/src/Concerns/IsPublishable.php index b840149..b482713 100644 --- a/src/Concerns/IsPublishable.php +++ b/src/Concerns/IsPublishable.php @@ -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; @@ -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() @@ -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'); @@ -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 + */ + public static function workflow(): string { - return 'draft'; + return config()->get('publisher.workflow'); } public static function query(): PublisherBuilder @@ -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 @@ -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 diff --git a/src/Concerns/QueriesPublishableModels.php b/src/Concerns/QueriesPublishableModels.php index 387ba14..089f0d5 100644 --- a/src/Concerns/QueriesPublishableModels.php +++ b/src/Concerns/QueriesPublishableModels.php @@ -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') @@ -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'); } diff --git a/src/Contracts/Publishable.php b/src/Contracts/Publishable.php index 40d5ab6..11fb9a0 100644 --- a/src/Contracts/Publishable.php +++ b/src/Contracts/Publishable.php @@ -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 */ - 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 diff --git a/src/Contracts/PublishingStatus.php b/src/Contracts/PublishingStatus.php new file mode 100644 index 0000000..58d22f7 --- /dev/null +++ b/src/Contracts/PublishingStatus.php @@ -0,0 +1,10 @@ +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'; diff --git a/tests/Feature/PublishedTest.php b/tests/Feature/PublishedTest.php index f1c0096..a5ec5d0 100644 --- a/tests/Feature/PublishedTest.php +++ b/tests/Feature/PublishedTest.php @@ -1,5 +1,6 @@ '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([ @@ -45,6 +46,6 @@ 'status' => 'draft', ]); - $this->assertEquals('draft', $post->status); + $this->assertEquals(Status::unpublished(), $post->status); $this->assertTrue($post->hasEverBeenPublished()); });