authorize('viewAny', Category::class); $locale = app()->getLocale(); $categories = Category::query() ->withCount('pages') ->when($request->has('is_visible'), fn ($q) => $q->where('is_visible', $request->boolean('is_visible'))) ->when($request->filled('search'), fn ($q) => $q->where("name->{$locale}", 'like', '%'.$request->string('search').'%')) ->orderBy('position') ->orderBy("name->{$locale}") ->paginate(perPage: min($request->integer('per_page', 25), 100)) ->withQueryString(); return CategoryResource::collection($categories); } public function store(CategoryRequest $request): JsonResponse { $this->authorize('create', Category::class); $category = new Category; $category->fill(TranslatablePayload::merge($category, $request->validated(), $category->translatable)); $category->save(); return CategoryResource::make($category)->response()->setStatusCode(201); } public function show(Category $category): CategoryResource { $this->authorize('view', $category); return CategoryResource::make($category->loadCount('pages')); } public function update(CategoryRequest $request, Category $category): CategoryResource { $this->authorize('update', $category); $category->fill(TranslatablePayload::merge($category, $request->validated(), $category->translatable)); $category->save(); return CategoryResource::make($category->loadCount('pages')); } public function destroy(Category $category): JsonResponse { // CategoryPolicy refuses while the category still holds pages, so this // answers 403 rather than orphaning content. $this->authorize('delete', $category); $category->delete(); return response()->json(status: 204); } }