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(), ]); } }