model = new LessonSlotModel(); } /** * GET /api/academic/lesson-slots */ public function index(): ResponseInterface { $slots = $this->model->orderBy('slot_number', 'ASC')->findAll(); $data = array_map([$this, 'slotToArray'], $slots); return $this->successResponse($data, 'Lesson slots'); } /** * POST /api/academic/lesson-slots */ public function create(): ResponseInterface { $input = $this->request->getJSON(true) ?? []; $data = [ 'slot_number' => (int) ($input['slot_number'] ?? 0), 'start_time' => (string) ($input['start_time'] ?? ''), 'end_time' => (string) ($input['end_time'] ?? ''), 'is_active' => isset($input['is_active']) ? (int) (bool) $input['is_active'] : 1, ]; if (!$this->model->validateStartBeforeEnd($data)) { return $this->errorResponse('End time must be after start time', null, null, 422); } $id = $this->model->insert($data); if ($id === false) { $msg = $this->model->errors()['end_time'] ?? implode(' ', $this->model->errors()); return $this->errorResponse($msg ?: 'Validation failed', null, null, 422); } $row = $this->model->find($id); return $this->successResponse($this->slotToArray($row), 'Lesson slot created', null, 201); } /** * PUT /api/academic/lesson-slots/{id} */ public function update($id): ResponseInterface { $id = (int) $id; $slot = $this->model->find($id); if (!$slot) { return $this->errorResponse('Lesson slot not found', null, null, 404); } $input = $this->request->getJSON(true) ?? []; $data = []; if (array_key_exists('slot_number', $input)) { $data['slot_number'] = (int) $input['slot_number']; } if (array_key_exists('start_time', $input)) { $data['start_time'] = (string) $input['start_time']; } if (array_key_exists('end_time', $input)) { $data['end_time'] = (string) $input['end_time']; } if (array_key_exists('is_active', $input)) { $data['is_active'] = (int) (bool) $input['is_active']; } if ($data !== [] && !$this->model->validateStartBeforeEnd(array_merge( ['start_time' => $data['start_time'] ?? $slot->start_time, 'end_time' => $data['end_time'] ?? $slot->end_time] ))) { return $this->errorResponse('End time must be after start time', null, null, 422); } $this->model->update($id, $data); if ($this->model->errors()) { return $this->errorResponse(implode(' ', $this->model->errors()), null, null, 422); } $row = $this->model->find($id); return $this->successResponse($this->slotToArray($row), 'Lesson slot updated'); } /** * DELETE /api/academic/lesson-slots/{id} */ public function delete($id): ResponseInterface { $id = (int) $id; if (!$this->model->find($id)) { return $this->errorResponse('Lesson slot not found', null, null, 404); } $this->model->delete($id); return $this->successResponse(null, 'Lesson slot deleted'); } protected function slotToArray($slot): array { if (is_array($slot)) { return [ 'id' => (int) ($slot['id'] ?? 0), 'slot_number' => (int) ($slot['slot_number'] ?? 0), 'start_time' => (string) ($slot['start_time'] ?? ''), 'end_time' => (string) ($slot['end_time'] ?? ''), ]; } return [ 'id' => (int) $slot->id, 'slot_number' => (int) $slot->slot_number, 'start_time' => (string) $slot->start_time, 'end_time' => (string) $slot->end_time, ]; } }