middleware('auth:sanctum')->only(['store', 'update', 'destroy']); } /** * Seznam kategorií (API, JSON). */ public function index(Request $request): JsonResponse { $perPage = (int) $request->get('per_page', 100); $categories = Category::query() ->with(['ediCategories', 'contests']) ->orderBy('order') ->paginate($perPage); return response()->json($categories); } /** * Vytvoření nové kategorie. * Autorizace přes CategoryPolicy@create. */ public function store(Request $request): JsonResponse { $this->authorize('create', Category::class); $data = $this->validateData($request); $relations = $this->validateRelations($request); $category = Category::create($data); if (array_key_exists('edi_category_ids', $relations)) { $category->ediCategories()->sync($relations['edi_category_ids']); } if (array_key_exists('contest_ids', $relations)) { $category->contests()->sync($relations['contest_ids']); } $category->load(['ediCategories', 'contests']); return response()->json($category, 201); } /** * Detail jedné kategorie. */ public function show(Category $category): JsonResponse { $category->load(['ediCategories', 'contests']); return response()->json($category); } /** * Aktualizace existující kategorie (partial update). * Autorizace přes CategoryPolicy@update. */ public function update(Request $request, Category $category): JsonResponse { $this->authorize('update', $category); $data = $this->validateData($request, partial: true); $relations = $this->validateRelations($request); $category->fill($data); $category->save(); if (array_key_exists('edi_category_ids', $relations)) { $category->ediCategories()->sync($relations['edi_category_ids']); } if (array_key_exists('contest_ids', $relations)) { $category->contests()->sync($relations['contest_ids']); } $category->load(['ediCategories', 'contests']); return response()->json($category); } /** * Smazání kategorie. * Autorizace přes CategoryPolicy@delete. */ public function destroy(Category $category): JsonResponse { $this->authorize('delete', $category); $category->delete(); return response()->json(null, 204); } /** * Společná validace dat pro store/update. */ protected function validateData(Request $request, bool $partial = false): array { $required = $partial ? 'sometimes' : 'required'; return $request->validate([ 'name' => [$required, 'string', 'max:255'], 'order' => [$required, 'integer'], ]); } /** * Validace ID relací (EDI kategorie a soutěže). */ protected function validateRelations(Request $request): array { return $request->validate([ 'edi_category_ids' => ['sometimes', 'array'], 'edi_category_ids.*' => ['integer', 'exists:edi_categories,id'], 'contest_ids' => ['sometimes', 'array'], 'contest_ids.*' => ['integer', 'exists:contests,id'], ]); } }