authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $validator = Validator::make($request->all(), [ 'user_ids' => ['nullable', 'array'], 'user_ids.*' => ['integer', 'exists:users,id'], 'student_ids' => ['nullable', 'array'], 'student_ids.*' => ['integer', 'exists:students,id'], 'school_year' => ['nullable', 'string', 'max:50'], 'roles' => ['nullable', 'array'], 'classes' => ['nullable', 'array'], ]); $validator->after(function ($validator): void { $data = $validator->getData(); $users = array_values(array_filter((array) ($data['user_ids'] ?? []), static fn ($v) => (int) $v > 0)); $students = array_values(array_filter((array) ($data['student_ids'] ?? []), static fn ($v) => (int) $v > 0)); if ($users === [] && $students === []) { $validator->errors()->add('user_ids', 'Provide at least one user id or student id.'); } }); if ($validator->fails()) { return response()->json([ 'message' => 'Validation failed.', 'errors' => $validator->errors(), ], 422); } $data = $validator->validated(); return $this->badgePdfService->generate( studentIds: $data['student_ids'] ?? [], userIds: $data['user_ids'] ?? [], schoolYear: $data['school_year'] ?? null, rolesMap: $data['roles'] ?? [], classesMap: $data['classes'] ?? [], actorId: $guard ); } public function printStatus(Request $request): JsonResponse { try { return response()->json([ 'ok' => true, 'data' => $this->badgePrintLogService->getStatus( $this->parseCombinedBadgeIds($request), $request->input('school_year') ), ]); } catch (Throwable) { return response()->json([ 'ok' => false, 'error' => 'Failed to query status', ], 500); } } public function logPrint(Request $request): JsonResponse { try { $guard = $this->authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $validator = Validator::make($request->all(), [ 'user_ids' => ['nullable', 'array'], 'user_ids.*' => ['integer', 'exists:users,id'], 'student_ids' => ['nullable', 'array'], 'student_ids.*' => ['integer', 'exists:students,id'], 'school_year' => ['nullable', 'string', 'max:50'], 'roles' => ['nullable', 'array'], 'classes' => ['nullable', 'array'], ]); $validator->after(function ($validator): void { $data = $validator->getData(); $users = array_values(array_filter((array) ($data['user_ids'] ?? []), static fn ($v) => (int) $v > 0)); $students = array_values(array_filter((array) ($data['student_ids'] ?? []), static fn ($v) => (int) $v > 0)); if ($users === [] && $students === []) { $validator->errors()->add('user_ids', 'Provide at least one user id or student id.'); } }); if ($validator->fails()) { return response()->json([ 'message' => 'Validation failed.', 'errors' => $validator->errors(), ], 422); } $data = $validator->validated(); $inserted = $this->badgePrintLogService->log( userIds: array_values(array_unique(array_merge( $data['user_ids'] ?? [], $data['student_ids'] ?? [] ))), actorId: $guard, schoolYear: $data['school_year'] ?? null, rolesMap: $data['roles'] ?? [], classesMap: $data['classes'] ?? [] ); return response()->json([ 'ok' => true, 'inserted' => $inserted, ]); } catch (Throwable $e) { return response()->json([ 'ok' => false, 'error' => $e->getMessage(), ], 500); } } public function formData(Request $request): JsonResponse { return response()->json([ 'ok' => true, 'data' => $this->badgeFormDataService->build( schoolYear: $request->input('school_year'), selectedUserIds: $this->parseStaffUserIds($request), selectedStudentIds: $this->parseStudentIds($request), activeRole: $request->input('active_role') ), ]); } /** * Staff user IDs for the badge picker (`users.id`). * * @return int[] */ private function parseStaffUserIds(Request $request): array { $ids = $request->input('user_ids', $request->query('user_ids', [])); if (is_string($ids)) { $ids = array_filter(array_map('trim', explode(',', $ids)), 'strlen'); } elseif (!is_array($ids)) { $ids = $ids ? [$ids] : []; } $ids = array_values(array_unique(array_map(static fn ($v) => (int) $v, $ids))); return array_values(array_filter($ids, static fn ($v) => $v > 0)); } /** * Combined `users.id` and `students.id` for print-status (same numeric space as stored in logs). * * @return int[] */ private function parseCombinedBadgeIds(Request $request): array { return array_values(array_unique(array_merge( $this->parseStaffUserIds($request), $this->parseStudentIds($request) ))); } /** * Student primary keys (`students.id`) from query or body. * * @return int[] */ private function parseStudentIds(Request $request): array { $ids = $request->input('student_ids', $request->query('student_ids', [])); if (is_string($ids)) { $ids = array_filter(array_map('trim', explode(',', $ids)), 'strlen'); } elseif (!is_array($ids)) { $ids = $ids ? [$ids] : []; } $ids = array_values(array_unique(array_map(static fn ($v) => (int) $v, $ids))); return array_values(array_filter($ids, static fn ($v) => $v > 0)); } /** * @return int|JsonResponse */ private function authenticatedUserIdOrUnauthorized(): int|JsonResponse { $userId = (int) (auth()->id() ?? 0); if ($userId <= 0) { return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401); } return $userId; } }