Skip to content

Commit 325e1b8

Browse files
[9.x] Fix validation on published field (#792)
1 parent 7fa9e5f commit 325e1b8

File tree

2 files changed

+116
-3
lines changed

2 files changed

+116
-3
lines changed

src/Http/Controllers/CP/ResourceController.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,13 @@ public function create(CreateRequest $request, Resource $resource)
9595

9696
public function store(StoreRequest $request, Resource $resource)
9797
{
98-
$resource
99-
->blueprint()
98+
$blueprint = $resource->blueprint();
99+
100+
if ($resource->hasPublishStates()) {
101+
$blueprint->ensureField($resource->publishedColumn(), ['type' => 'toggle']);
102+
}
103+
104+
$blueprint
100105
->fields()
101106
->addValues($request->all())
102107
->validator()
@@ -178,7 +183,13 @@ public function update(UpdateRequest $request, Resource $resource, Model $model)
178183
{
179184
$model = $model->fromWorkingCopy();
180185

181-
$resource->blueprint()
186+
$blueprint = $resource->blueprint();
187+
188+
if ($resource->hasPublishStates()) {
189+
$blueprint->ensureField($resource->publishedColumn(), ['type' => 'toggle']);
190+
}
191+
192+
$blueprint
182193
->fields()
183194
->setParent($model)
184195
->addValues($request->except($resource->primaryKey()))

tests/Http/Controllers/CP/ResourceControllerTest.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,77 @@ public function can_store_resource_and_ensure_date_comparison_validation_works()
284284
]);
285285
}
286286

287+
#[Test]
288+
public function can_store_resource_with_required_if_published_validation()
289+
{
290+
$postBlueprint = Blueprint::find('runway::post');
291+
292+
Blueprint::shouldReceive('find')->with('user')->andReturn(new \Statamic\Fields\Blueprint);
293+
Blueprint::shouldReceive('find')->with('runway::author')->andReturn(new \Statamic\Fields\Blueprint);
294+
Blueprint::shouldReceive('find')->with('runway::post')->andReturn($postBlueprint->ensureField('membership_status', [
295+
'type' => 'select',
296+
'options' => ['free' => 'Free', 'paid' => 'Paid'],
297+
'validate' => ['required_if:published,true'],
298+
]));
299+
Blueprint::shouldReceive('getAdditionalNamespaces')->andReturn(collect(['runway' => base_path('resources/blueprints/runway')]))->zeroOrMoreTimes();
300+
301+
$author = Author::factory()->create();
302+
$user = User::make()->makeSuper()->save();
303+
304+
// Publishing without the required field should fail
305+
$this
306+
->actingAs($user)
307+
->post(cp_route('runway.store', ['resource' => 'post']), [
308+
'published' => true,
309+
'title' => 'Test Post',
310+
'slug' => 'test-post',
311+
'body' => 'Test body',
312+
'author_id' => [$author->id],
313+
'membership_status' => null,
314+
])
315+
->assertSessionHasErrors('membership_status');
316+
317+
$this->assertDatabaseMissing('posts', [
318+
'title' => 'Test Post',
319+
]);
320+
}
321+
322+
#[Test]
323+
public function can_store_resource_as_draft_without_required_if_published_field()
324+
{
325+
$postBlueprint = Blueprint::find('runway::post');
326+
327+
Blueprint::shouldReceive('find')->with('user')->andReturn(new \Statamic\Fields\Blueprint);
328+
Blueprint::shouldReceive('find')->with('runway::author')->andReturn(new \Statamic\Fields\Blueprint);
329+
Blueprint::shouldReceive('find')->with('runway::post')->andReturn($postBlueprint->ensureField('membership_status', [
330+
'type' => 'select',
331+
'options' => ['free' => 'Free', 'paid' => 'Paid'],
332+
'validate' => ['required_if:published,true'],
333+
]));
334+
Blueprint::shouldReceive('getAdditionalNamespaces')->andReturn(collect(['runway' => base_path('resources/blueprints/runway')]))->zeroOrMoreTimes();
335+
336+
$author = Author::factory()->create();
337+
$user = User::make()->makeSuper()->save();
338+
339+
// Saving as draft without the required field should succeed
340+
$this
341+
->actingAs($user)
342+
->post(cp_route('runway.store', ['resource' => 'post']), [
343+
'published' => false,
344+
'title' => 'Draft Post',
345+
'slug' => 'draft-post',
346+
'body' => 'Draft body',
347+
'author_id' => [$author->id],
348+
'membership_status' => null,
349+
])
350+
->assertOk();
351+
352+
$this->assertDatabaseHas('posts', [
353+
'title' => 'Draft Post',
354+
'published' => false,
355+
]);
356+
}
357+
287358
#[Test]
288359
public function can_edit_resource()
289360
{
@@ -692,4 +763,35 @@ public function can_update_resource_if_model_is_user_model()
692763
'group_id' => 'admins',
693764
]);
694765
}
766+
767+
#[Test]
768+
public function can_update_resource_with_required_if_published_validation()
769+
{
770+
$postBlueprint = Blueprint::find('runway::post');
771+
772+
Blueprint::shouldReceive('find')->with('user')->andReturn(new \Statamic\Fields\Blueprint);
773+
Blueprint::shouldReceive('find')->with('runway::author')->andReturn(new \Statamic\Fields\Blueprint);
774+
Blueprint::shouldReceive('find')->with('runway::post')->andReturn($postBlueprint->ensureField('membership_status', [
775+
'type' => 'select',
776+
'options' => ['free' => 'Free', 'paid' => 'Paid'],
777+
'validate' => ['required_if:published,true'],
778+
]));
779+
Blueprint::shouldReceive('getAdditionalNamespaces')->andReturn(collect(['runway' => base_path('resources/blueprints/runway')]))->zeroOrMoreTimes();
780+
781+
$post = Post::factory()->create(['published' => false]);
782+
$user = User::make()->makeSuper()->save();
783+
784+
// Publishing without the required field should fail
785+
$this
786+
->actingAs($user)
787+
->patch(cp_route('runway.update', ['resource' => 'post', 'model' => $post->id]), [
788+
'published' => true,
789+
'title' => $post->title,
790+
'slug' => $post->slug,
791+
'body' => $post->body,
792+
'author_id' => [$post->author_id],
793+
'membership_status' => null,
794+
])
795+
->assertSessionHasErrors('membership_status');
796+
}
695797
}

0 commit comments

Comments
 (0)