PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); } catch (PDOException $e) { jsonError('Koneksi database gagal: ' . $e->getMessage(), 500); } } return $pdo; } // Response helpers — bersihkan output buffer dulu agar tidak ada PHP warning yang merusak JSON function jsonOk($data = null, string $msg = 'OK'): void { if (ob_get_level()) ob_clean(); echo json_encode(['success' => true, 'message' => $msg, 'data' => $data], JSON_UNESCAPED_UNICODE); exit(); } function jsonError(string $msg, int $code = 400): void { if (ob_get_level()) ob_clean(); http_response_code($code); echo json_encode(['success' => false, 'message' => $msg], JSON_UNESCAPED_UNICODE); exit(); } // Auth check function requireAuth(): array { if (empty($_SESSION['user'])) { jsonError('Tidak terautentikasi. Silakan login.', 401); } return $_SESSION['user']; } function requireEdit(): array { $user = requireAuth(); if (!$user['can_edit']) jsonError('Anda tidak memiliki hak akses edit.', 403); return $user; } // Input helper function body(): array { $raw = file_get_contents('php://input'); return json_decode($raw, true) ?? []; } function getParam(string $key, $default = null) { return $_GET[$key] ?? $default; }