139 lines
No EOL
4.5 KiB
PHP
139 lines
No EOL
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Post;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use App\Http\Requests\Post\ListPostRequest;
|
|
use App\Http\Resources\PaginatedResource;
|
|
|
|
class PostController extends Controller
|
|
{
|
|
public function index(ListPostRequest $request): JsonResponse
|
|
{
|
|
$validated = $request->validated();
|
|
$perPage = min($request->input('per_page', 10), 100);
|
|
$sortBy = $request->input('sort_by', 'created_at');
|
|
$sortOrder = $request->input('sort_order', 'desc');
|
|
|
|
$allowedSortFields = ['created_at', 'title', 'views'];
|
|
$sortBy = in_array($sortBy, $allowedSortFields) ? $sortBy : 'created_at';
|
|
$sortOrder = in_array($sortOrder, ['asc', 'desc']) ? $sortOrder : 'desc';
|
|
|
|
$query = Post::with(['author:id,name', 'category:id,name'])
|
|
->when($request->authorId, fn($q) => $q->where('author_id', $request->authorId))
|
|
->when($request->category, fn($q) => $q->whereHas('category', fn($q) =>
|
|
$q->where('name', $request->category)
|
|
))
|
|
->when($request->search, fn($q) => $q->where(fn($q) =>
|
|
$q->where('title', 'like', "%{$request->search}%")
|
|
->orWhere('content', 'like', "%{$request->search}%")
|
|
));
|
|
|
|
$query->orderBy($sortBy, $sortOrder);
|
|
$posts = $query->paginate($perPage);
|
|
|
|
return response()->success([
|
|
'posts' => new PaginatedResource($posts)
|
|
]);
|
|
}
|
|
|
|
public function show(Request $request, Post $post): JsonResponse
|
|
{
|
|
$this->postViewService->recordView($post, $request->ip());
|
|
|
|
$post->load(['author:id,name', 'comments.author:id,name']);
|
|
|
|
return response()->json([
|
|
'post' => [
|
|
'id' => $post->id,
|
|
'title' => $post->title,
|
|
'content' => $post->content,
|
|
'author' => $post->author,
|
|
'comments' => $post->comments->map(fn($comment) => [
|
|
'id' => $comment->id,
|
|
'content' => $comment->content,
|
|
'author' => $comment->author,
|
|
'created_at' => $comment->created_at,
|
|
]),
|
|
'created_at' => $post->created_at,
|
|
]
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'title' => 'required|string|max:255',
|
|
'content' => 'required|string',
|
|
'category_id' => 'nullable|exists:categories,id',
|
|
'summary' => 'nullable|string|max:500',
|
|
]);
|
|
|
|
$post = $request->user()->posts()->create($validated);
|
|
|
|
return response()->json([
|
|
'message' => 'Post created successfully',
|
|
'post' => [
|
|
'id' => $post->id,
|
|
'title' => $post->title,
|
|
'content' => $post->content,
|
|
'author' => [
|
|
'id' => $request->user()->id,
|
|
'name' => $request->user()->name,
|
|
],
|
|
'created_at' => $post->created_at,
|
|
]
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, Post $post): JsonResponse
|
|
{
|
|
$this->authorize('update', $post);
|
|
|
|
$validated = $request->validate([
|
|
'title' => 'sometimes|string|max:255',
|
|
'content' => 'sometimes|string',
|
|
'category_id' => 'nullable|exists:categories,id',
|
|
'summary' => 'nullable|string|max:500',
|
|
]);
|
|
|
|
$post->update($validated);
|
|
|
|
return response()->json([
|
|
'message' => 'Post updated successfully',
|
|
'post' => [
|
|
'id' => $post->id,
|
|
'title' => $post->title,
|
|
'content' => $post->content,
|
|
'author' => [
|
|
'id' => $post->author->id,
|
|
'name' => $post->author->name,
|
|
],
|
|
'updated_at' => $post->updated_at,
|
|
]
|
|
]);
|
|
}
|
|
|
|
public function destroy(Post $post): JsonResponse
|
|
{
|
|
$this->authorize('delete', $post);
|
|
|
|
$post->delete();
|
|
|
|
return response()->json([
|
|
'message' => 'Post deleted successfully'
|
|
]);
|
|
}
|
|
|
|
public function popular(Request $request): JsonResponse
|
|
{
|
|
return response()->json([
|
|
'data' => $this->postViewService->getPopularPosts(),
|
|
]);
|
|
}
|
|
}
|