getSecurityUser(); $subjectId = $request->query->get('subjectId'); $result = ($this->handler)(new GetStudentHomeworkQuery( studentId: $user->userId(), tenantId: $user->tenantId(), subjectId: is_string($subjectId) && $subjectId !== '' ? $subjectId : null, )); return new JsonResponse([ 'data' => array_map($this->serializeListItem(...), $result), ]); } #[Route('/api/me/homework/{id}', name: 'api_student_homework_detail', methods: ['GET'])] public function detail(string $id): JsonResponse { $user = $this->getSecurityUser(); $tenantId = TenantId::fromString($user->tenantId()); $homework = $this->homeworkRepository->findById(HomeworkId::fromString($id), $tenantId); if ($homework === null) { throw new NotFoundHttpException('Devoir non trouvé.'); } $this->assertHomeworkBelongsToStudentClass($user, $homework); $attachments = $this->attachmentRepository->findByHomeworkId($homework->id); $subjects = $this->displayReader->subjectDisplay($user->tenantId(), (string) $homework->subjectId); $teacherNames = $this->displayReader->teacherNames($user->tenantId(), (string) $homework->teacherId); $detail = StudentHomeworkDetailDto::fromDomain( $homework, $subjects[(string) $homework->subjectId]['name'] ?? '', $subjects[(string) $homework->subjectId]['color'] ?? null, $teacherNames[(string) $homework->teacherId] ?? '', $attachments, ); return new JsonResponse(['data' => $this->serializeDetail($detail)]); } #[Route('/api/me/homework/{homeworkId}/attachments/{attachmentId}', name: 'api_student_homework_attachment', methods: ['GET'])] public function downloadAttachment(string $homeworkId, string $attachmentId): BinaryFileResponse { $user = $this->getSecurityUser(); $tenantId = TenantId::fromString($user->tenantId()); $homework = $this->homeworkRepository->findById(HomeworkId::fromString($homeworkId), $tenantId); if ($homework === null) { throw new NotFoundHttpException('Devoir non trouvé.'); } $this->assertHomeworkBelongsToStudentClass($user, $homework); $attachments = $this->attachmentRepository->findByHomeworkId($homework->id); foreach ($attachments as $attachment) { if ((string) $attachment->id === $attachmentId) { $fullPath = $this->uploadsDir . '/' . $attachment->filePath; $realPath = realpath($fullPath); $realUploadsDir = realpath($this->uploadsDir); if ($realPath === false || $realUploadsDir === false || !str_starts_with($realPath, $realUploadsDir)) { throw new NotFoundHttpException('Pièce jointe non trouvée.'); } $response = new BinaryFileResponse($realPath); $response->setContentDisposition( ResponseHeaderBag::DISPOSITION_INLINE, $attachment->filename, ); return $response; } } throw new NotFoundHttpException('Pièce jointe non trouvée.'); } private function assertHomeworkBelongsToStudentClass(SecurityUser $user, Homework $homework): void { $classId = $this->studentClassReader->currentClassId( $user->userId(), TenantId::fromString($user->tenantId()), ); if ($classId === null || (string) $homework->classId !== $classId) { throw new NotFoundHttpException('Devoir non trouvé.'); } } private function getSecurityUser(): SecurityUser { $user = $this->security->getUser(); if (!$user instanceof SecurityUser) { throw new AccessDeniedHttpException('Authentification requise.'); } return $user; } /** * @return array */ private function serializeListItem(StudentHomeworkDto $dto): array { return [ 'id' => $dto->id, 'subjectId' => $dto->subjectId, 'subjectName' => $dto->subjectName, 'subjectColor' => $dto->subjectColor, 'teacherId' => $dto->teacherId, 'teacherName' => $dto->teacherName, 'title' => $dto->title, 'description' => $dto->description, 'dueDate' => $dto->dueDate, 'createdAt' => $dto->createdAt, 'hasAttachments' => $dto->hasAttachments, ]; } /** * @return array */ private function serializeDetail(StudentHomeworkDetailDto $dto): array { return [ 'id' => $dto->id, 'subjectId' => $dto->subjectId, 'subjectName' => $dto->subjectName, 'subjectColor' => $dto->subjectColor, 'teacherId' => $dto->teacherId, 'teacherName' => $dto->teacherName, 'title' => $dto->title, 'description' => $dto->description, 'dueDate' => $dto->dueDate, 'createdAt' => $dto->createdAt, 'attachments' => array_map( static fn ($a): array => [ 'id' => $a->id, 'filename' => $a->filename, 'fileSize' => $a->fileSize, 'mimeType' => $a->mimeType, ], $dto->attachments, ), ]; } }