<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user()->can('create', Post::class);
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255', 'unique:posts'],
'body' => ['required', 'string', 'min:100'],
'status' => ['required', Rule::in(['draft', 'published'])],
'published_at' => ['nullable', 'date', 'after:now'],
'tags' => ['array', 'max:5'],
'tags.*' => ['string', 'max:50'],
'featured_image' => ['nullable', 'image', 'max:2048'],
];
}
public function messages(): array
{
return [
'title.unique' => 'A post with this title already exists.',
'body.min' => 'Post content must be at least 100 characters.',
'tags.max' => 'You can add a maximum of 5 tags.',
];
}
public function attributes(): array
{
return [
'published_at' => 'publication date',
'featured_image' => 'image',
];
}
protected function prepareForValidation(): void
{
$this->merge([
'slug' => str($this->title)->slug(),
]);
}
}
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StorePostRequest;
use App\Http\Requests\UpdatePostRequest;
use App\Models\Post;
class PostController extends Controller
{
public function store(StorePostRequest $request)
{
// Validation already passed, authorization already checked
$post = Post::create($request->validated());
if ($request->hasFile('featured_image')) {
$post->addMedia($request->file('featured_image'))
->toMediaCollection('featured');
}
return redirect()
->route('posts.show', $post)
->with('success', 'Post created successfully!');
}
public function update(UpdatePostRequest $request, Post $post)
{
$post->update($request->validated());
return redirect()
->route('posts.show', $post)
->with('success', 'Post updated successfully!');
}
}