table('classes') ->select('classes.id, classes.name, classes.grade, classes.major, classes.wali_user_id, users.name AS wali_user_name') ->join('users', 'users.id = classes.wali_user_id', 'left') ->orderBy('classes.grade', 'ASC') ->orderBy('classes.major', 'ASC') ->orderBy('classes.name', 'ASC') ->get() ->getResultArray(); $data = array_map(static function ($r) { $grade = $r['grade'] !== null ? trim((string) $r['grade']) : ''; $major = $r['major'] !== null ? trim((string) $r['major']) : ''; $name = $r['name'] !== null ? trim((string) $r['name']) : ''; $parts = array_filter([$grade, $major, $name], static fn ($v) => $v !== ''); $fullLabel = implode(' ', $parts) !== '' ? implode(' ', $parts) : (string) $r['name']; return [ 'id' => (int) $r['id'], 'grade' => $grade, 'major' => $major, 'name' => $name, 'wali_user_id' => $r['wali_user_id'] !== null ? (int) $r['wali_user_id'] : null, 'wali_name' => $r['wali_user_name'] !== null ? (string) $r['wali_user_name'] : null, 'full_label' => $fullLabel, ]; }, $rows); return $this->successResponse($data, 'Classes'); } /** * POST /api/academic/classes * Requires: grade, major, name (rombel). Optional: wali_user_id. */ public function create(): ResponseInterface { $payload = $this->request->getJSON(true) ?? []; $data = [ 'name' => $payload['name'] ?? '', 'grade' => $payload['grade'] ?? '', 'major' => $payload['major'] ?? '', 'wali_user_id' => isset($payload['wali_user_id']) && $payload['wali_user_id'] !== '' && $payload['wali_user_id'] !== null ? (int) $payload['wali_user_id'] : null, ]; $model = new ClassModel(); if (!$model->validate($data)) { return $this->errorResponse( implode(' ', $model->errors()), $model->errors(), null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY ); } $id = $model->insert($data); if ($id === false) { return $this->errorResponse('Gagal menyimpan kelas', null, null, ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } $row = $model->find($id); $fullLabel = trim($row->grade . ' ' . $row->major . ' ' . $row->name) ?: (string) $row->name; $out = [ 'id' => (int) $row->id, 'grade' => (string) $row->grade, 'major' => (string) $row->major, 'name' => (string) $row->name, 'wali_user_id' => $row->wali_user_id !== null ? (int) $row->wali_user_id : null, 'full_label' => $fullLabel, ]; return $this->successResponse($out, 'Kelas berhasil ditambahkan', null, ResponseInterface::HTTP_CREATED); } /** * PUT /api/academic/classes/{id} */ public function update(int $id): ResponseInterface { $model = new ClassModel(); $row = $model->find($id); if (!$row) { return $this->errorResponse('Kelas tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND); } $payload = $this->request->getJSON(true) ?? []; $data = [ 'id' => $id, 'name' => $payload['name'] ?? $row->name, 'grade' => $payload['grade'] ?? $row->grade, 'major' => $payload['major'] ?? $row->major, 'wali_user_id' => isset($payload['wali_user_id']) && $payload['wali_user_id'] !== '' && $payload['wali_user_id'] !== null ? (int) $payload['wali_user_id'] : null, ]; if (!$model->validate($data)) { return $this->errorResponse( implode(' ', $model->errors()), $model->errors(), null, ResponseInterface::HTTP_UNPROCESSABLE_ENTITY ); } unset($data['id']); if ($model->update($id, $data) === false) { return $this->errorResponse('Gagal mengubah kelas', null, null, ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } $updated = $model->find($id); $fullLabel = trim($updated->grade . ' ' . $updated->major . ' ' . $updated->name) ?: (string) $updated->name; $out = [ 'id' => (int) $updated->id, 'grade' => (string) $updated->grade, 'major' => (string) $updated->major, 'name' => (string) $updated->name, 'wali_user_id' => $updated->wali_user_id !== null ? (int) $updated->wali_user_id : null, 'full_label' => $fullLabel, ]; return $this->successResponse($out, 'Kelas berhasil diubah'); } /** * DELETE /api/academic/classes/{id} */ public function delete(int $id): ResponseInterface { $model = new ClassModel(); if (!$model->find($id)) { return $this->errorResponse('Kelas tidak ditemukan', null, null, ResponseInterface::HTTP_NOT_FOUND); } if ($model->delete($id) === false) { return $this->errorResponse('Gagal menghapus kelas', null, null, ResponseInterface::HTTP_INTERNAL_SERVER_ERROR); } return $this->successResponse(null, 'Kelas berhasil dihapus'); } }