Skip to content

Commit cf35953

Browse files
authored
[Fix] Prevent multiple current records after publishing draft (#39)
* [Fix] Prevent multiple current records after publishing draft * Fix styling --------- Co-authored-by: oddvalue <[email protected]>
1 parent 1a4e8fa commit cf35953

File tree

3 files changed

+69
-35
lines changed

3 files changed

+69
-35
lines changed

Diff for: src/Concerns/HasDrafts.php

+20-11
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,19 @@ public function getDraftableAttributes(): array
147147

148148
public function setCurrent(): void
149149
{
150-
$oldCurrent = $this->revisions()->withDrafts()->current()->excludeRevision($this)->first();
150+
$this->{$this->getIsCurrentColumn()} = true;
151151

152-
static::saved(function (Model $model) use ($oldCurrent): void {
153-
if ($model->isNot($this) || ! $oldCurrent) {
152+
static::saved(function (Model $model): void {
153+
if ($model->isNot($this)) {
154154
return;
155155
}
156156

157-
$oldCurrent->{$this->getIsCurrentColumn()} = false;
158-
$oldCurrent->timestamps = false;
159-
$oldCurrent->saveQuietly();
157+
$this->revisions()
158+
->withDrafts()
159+
->current()
160+
->excludeRevision($this)
161+
->update([$this->getIsCurrentColumn() => false]);
160162
});
161-
162-
$this->{$this->getIsCurrentColumn()} = true;
163163
}
164164

165165
public function setLive(): void
@@ -199,7 +199,9 @@ public function setLive(): void
199199
if ($related = $this->{$relationName}) {
200200
$replicated = $related->replicate();
201201

202-
$method = method_exists($replicated, 'getDraftableAttributes') ? 'getDraftableAttributes' : 'getAttributes';
202+
$method = method_exists($replicated, 'getDraftableAttributes')
203+
? 'getDraftableAttributes'
204+
: 'getAttributes';
203205

204206
$published->{$relationName}()->create($replicated->$method());
205207
}
@@ -209,7 +211,9 @@ public function setLive(): void
209211
$this->{$relationName}()->get()->each(function ($model) use ($published, $relationName) {
210212
$replicated = $model->replicate();
211213

212-
$method = method_exists($replicated, 'getDraftableAttributes') ? 'getDraftableAttributes' : 'getAttributes';
214+
$method = method_exists($replicated, 'getDraftableAttributes')
215+
? 'getDraftableAttributes'
216+
: 'getAttributes';
213217

214218
$published->{$relationName}()->create($replicated->$method());
215219
});
@@ -380,11 +384,16 @@ public function getIsCurrentColumn(): string
380384

381385
public function getUuidColumn(): string
382386
{
383-
return defined(static::class.'::UUID')
387+
return defined(static::class . '::UUID')
384388
? static::UUID
385389
: config('drafts.column_names.uuid', 'uuid');
386390
}
387391

392+
public function isCurrent(): bool
393+
{
394+
return $this->{$this->getIsCurrentColumn()} ?? false;
395+
}
396+
388397
/*
389398
|--------------------------------------------------------------------------
390399
| RELATIONS

Diff for: src/Scopes/PublishingScope.php

+24-24
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,30 @@ public function extend(Builder $builder): void
3131
}
3232
}
3333

34-
// protected function addPublish(Builder $builder): void
35-
// {
36-
// $builder->macro('publish', function (Builder $builder) {
37-
// $builder->withDrafts();
38-
//
39-
// return $builder->update([$builder->getModel()->getIsPublishedColumn() => now()]);
40-
// });
41-
// }
42-
//
43-
// protected function addUnpublish(Builder $builder): void
44-
// {
45-
// $builder->macro('unpublish', function (Builder $builder) {
46-
// return $builder->update([$builder->getModel()->getIsPublishedColumn() => null]);
47-
// });
48-
// }
49-
//
50-
// protected function addSchedule(Builder $builder): void
51-
// {
52-
// $builder->macro('schedule', function (Builder $builder, string | \DateTimeInterface $date) {
53-
// $builder->withDrafts();
54-
//
55-
// return $builder->update([$builder->getModel()->getIsPublishedColumn() => $date]);
56-
// });
57-
// }
34+
// protected function addPublish(Builder $builder): void
35+
// {
36+
// $builder->macro('publish', function (Builder $builder) {
37+
// $builder->withDrafts();
38+
//
39+
// return $builder->update([$builder->getModel()->getIsPublishedColumn() => now()]);
40+
// });
41+
// }
42+
//
43+
// protected function addUnpublish(Builder $builder): void
44+
// {
45+
// $builder->macro('unpublish', function (Builder $builder) {
46+
// return $builder->update([$builder->getModel()->getIsPublishedColumn() => null]);
47+
// });
48+
// }
49+
//
50+
// protected function addSchedule(Builder $builder): void
51+
// {
52+
// $builder->macro('schedule', function (Builder $builder, string | \DateTimeInterface $date) {
53+
// $builder->withDrafts();
54+
//
55+
// return $builder->update([$builder->getModel()->getIsPublishedColumn() => $date]);
56+
// });
57+
// }
5858

5959
protected function addPublished(Builder $builder): void
6060
{

Diff for: tests/PublishingTest.php

+25
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,28 @@
6666
expect(Post::withoutDrafts()->pluck('id'))
6767
->toHaveCount(1);
6868
});
69+
70+
it('can publish a draft that is not the current one', function () {
71+
\Oddvalue\LaravelDrafts\Facades\LaravelDrafts::withDrafts();
72+
73+
Post::factory()->create(['title' => 'a']);
74+
75+
$post = Post::where('title', 'a')->first();
76+
$post->title = 'b';
77+
$b = $post->saveAsDraft();
78+
79+
$post = Post::where('title', 'b')->first();
80+
$post->title = 'c';
81+
$post->saveAsDraft();
82+
83+
expect(Post::where('title', 'a')->first()->isPublished())->toBeTrue();
84+
expect(Post::where('title', 'c')->first()->isCurrent())->toBeTrue();
85+
86+
$draftB = Post::where('title', 'b')->first();
87+
$draftB->setLive();
88+
$draftB->save();
89+
90+
expect(Post::where('title', 'a')->first()->isPublished())->toBeFalse();
91+
expect(Post::where('title', 'b')->first()->isPublished())->toBeTrue();
92+
expect(Post::current()->count())->toBe(1);
93+
});

0 commit comments

Comments
 (0)