user($request); try { $schedule = $this->createSchedule->execute( new CreateScheduleRequest( user: $user, setId: $input->integer('setId'), levelId: $input->integer('levelId'), startDate: $input->string('startDate'), targetDate: $input->string('targetDate'), ), ); } catch (BadRequestException $exception) { return new JsonResponse( ['error' => $exception->getMessage()], 400, ); } catch (NotFoundException $exception) { return new JsonResponse( ['error' => $exception->getMessage()], 404, ); } return new JsonResponse( ['schedule' => $this->detailPayload($schedule)], 201, ); } public function index(Request $request): JsonResponse { $schedules = array_map( function (Schedule $schedule): array { return $this->summaryPayload($schedule); }, $this->listSchedules->execute($this->user($request)), ); return new JsonResponse(['schedules' => $schedules]); } public function show(Request $request, int $scheduleId): JsonResponse { try { $schedule = $this->getSchedule->execute( new GetScheduleRequest( scheduleId: $scheduleId, user: $this->user($request), ), ); } catch (NotFoundException $exception) { return new JsonResponse( ['error' => $exception->getMessage()], 404, ); } return new JsonResponse([ 'schedule' => $this->detailPayload($schedule), ]); } public function assignments(Request $request): JsonResponse { $input = new RequestInput($request); $date = $input->string('date'); try { $assignments = $this->listAssignmentsForDate->execute( new ListAssignmentsForDateRequest( user: $this->user($request), date: $date, ), ); } catch (BadRequestException $exception) { return new JsonResponse( ['error' => $exception->getMessage()], 400, ); } return new JsonResponse([ 'date' => $date, 'assignments' => array_map( function (AssignmentForDate $assignment): array { return $this->assignmentForDatePayload($assignment); }, $assignments, ), ]); } public function updateAssignment( Request $request, int $assignmentId, ): JsonResponse { $input = new RequestInput($request); try { $assignment = $this->setAssignmentCompletion->execute( new SetAssignmentCompletionRequest( assignmentId: $assignmentId, user: $this->user($request), completed: $input->boolean('completed'), ), ); } catch (BadRequestException $exception) { return new JsonResponse( ['error' => $exception->getMessage()], 400, ); } catch (NotFoundException $exception) { return new JsonResponse( ['error' => $exception->getMessage()], 404, ); } return new JsonResponse([ 'assignment' => [ 'id' => $assignment->getId(), 'completedAt' => $assignment->getCompletedAt() ?->format(DATE_ATOM), ], ]); } /** * @return array */ private function summaryPayload(Schedule $schedule): array { return [ 'id' => $schedule->getId(), 'set' => [ 'name' => $schedule->getSetName(), ], 'elementKind' => $schedule->getElementKind(), 'startDate' => $schedule->getStartDate()->format('Y-m-d'), 'targetDate' => $schedule->getTargetDate()->format('Y-m-d'), 'assignmentCount' => count($schedule->getAssignments()), ]; } /** * @return array */ private function detailPayload(Schedule $schedule): array { $payload = $this->summaryPayload($schedule); $payload['days'] = $this->dayPayloads($schedule); return $payload; } /** * @return list}> */ private function dayPayloads(Schedule $schedule): array { $assignmentsByDate = []; foreach ($schedule->getAssignments() as $assignment) { $date = $assignment->getScheduledDate()->format('Y-m-d'); $assignmentsByDate[$date][] = $this->assignmentPayload( $assignment, ); } $days = []; $date = $schedule->getStartDate(); while ($date <= $schedule->getTargetDate()) { $formattedDate = $date->format('Y-m-d'); $days[] = [ 'date' => $formattedDate, 'assignments' => $assignmentsByDate[$formattedDate] ?? [], ]; $date = $date->modify('+1 day'); } return $days; } /** * @return array{id: int, completedAt: string|null, element: array{ * name: string, * kind: string, * path: list * }} */ private function assignmentPayload( ScheduleAssignment $assignment, ): array { return [ 'id' => $assignment->getId(), 'completedAt' => $assignment->getCompletedAt() ?->format(DATE_ATOM), 'element' => [ 'name' => $assignment->getName(), 'kind' => $assignment->getKind(), 'path' => $assignment->getPath(), ], ]; } /** * @return array */ private function assignmentForDatePayload( AssignmentForDate $assignmentForDate, ): array { $assignment = $assignmentForDate->getAssignment(); return [ 'id' => $assignment->getId(), 'schedule' => [ 'id' => $assignmentForDate->getScheduleId(), 'set' => [ 'name' => $assignmentForDate->getSetName(), ], ], 'element' => [ 'name' => $assignment->getName(), 'kind' => $assignment->getKind(), 'path' => $assignment->getPath(), ], ]; } private function user(Request $request): User { /** @var User $user */ $user = $request->attributes->get('user'); return $user; } }