"error", "message" => "Metode pengiriman data salah. Gunakan POST." ]); exit(); } // 2. [OPSIONAL] Kunci API Keamanan (Ganti TOKEN_KEAMANAN_ANDA jika ingin diaktifkan) define('API_KEY_REQUIRED', false); // Ubah ke true jika ingin mengaktifkan otentikasi kunci API define('SECURE_API_KEY', 'AB2_GRT_SECURE_TOKEN_2026'); if (API_KEY_REQUIRED) { $headers = apache_request_headers(); $providedKey = isset($headers['X-API-KEY']) ? $headers['X-API-KEY'] : (isset($_GET['api_key']) ? $_GET['api_key'] : ''); if ($providedKey !== SECURE_API_KEY) { http_response_code(401); echo json_encode([ "status" => "error", "message" => "Akses tidak sah. Kunci API tidak cocok atau tidak terkirim." ]); exit(); } } // 3. Membaca & Memparsing Input JSON dari Android $rawInput = file_get_contents("php://input"); $data = json_decode($rawInput, true); if (empty($data)) { http_response_code(400); echo json_encode([ "status" => "error", "message" => "Format JSON tidak valid atau data kosong." ]); exit(); } // 4. Validasi Keberadaan Field Utama $requiredFields = ['date', 'wilayah', 'depo', 'namaToko', 'kodeToko', 'namaMotoris', 'kodeDa', 'ecg', 'omsetRupiah', 'reportText']; foreach ($requiredFields as $field) { if (!isset($data[$field]) || trim($data[$field]) === '') { http_response_code(400); echo json_encode([ "status" => "error", "message" => "Data tidak lengkap. Field '" . $field . "' wajib diisi." ]); exit(); } } // 5. Sanitasi & Ekstraksi Data $tanggal = htmlspecialchars(strip_tags(trim($data['date']))); $wilayah = htmlspecialchars(strip_tags(trim($data['wilayah']))); $depo = htmlspecialchars(strip_tags(trim($data['depo']))); $namaToko = htmlspecialchars(strip_tags(trim($data['namaToko']))); $kodeToko = htmlspecialchars(strip_tags(trim($data['kodeToko']))); $namaMotoris = htmlspecialchars(strip_tags(trim($data['namaMotoris']))); $kodeDa = htmlspecialchars(strip_tags(trim($data['kodeDa']))); $ecg = (int) $data['ecg']; $reportText = trim($data['reportText']); // Konversi Omset Rupiah ke format angka decimal bersih (misal "692.725" -> 692725.00) $cleanOmset = preg_replace('/[^0-9]/', '', $data['omsetRupiah']); $omsetRupiah = (float) $cleanOmset; // 6. Penanganan Foto Base64 (Konversi ke File fisik JPG) $photoPath = null; if (isset($data['photoBase64']) && !empty($data['photoBase64'])) { $base64Image = $data['photoBase64']; // Hilangkan prefix jika dikirim lengkap dengan header base64 data uri (misal: "data:image/jpeg;base64,") if (preg_match('/^data:image\/(\w+);base64,/', $base64Image, $type)) { $base64Image = substr($base64Image, strpos($base64Image, ',') + 1); $fileType = strtolower($type[1]); // jpeg, png, dll. } else { $fileType = 'jpg'; // default fallback } $decodedImage = base64_decode($base64Image); if ($decodedImage === false) { http_response_code(400); echo json_encode([ "status" => "error", "message" => "Format dekoding Base64 foto tidak valid." ]); exit(); } // Buat direktori unggahan jika belum ada $uploadDir = __DIR__ . '/../../uploads/'; if (!file_exists($uploadDir)) { mkdir($uploadDir, 0755, true); } // Nama file yang aman dan unik $fileName = 'NOTA_' . $kodeDa . '_' . time() . '_' . uniqid() . '.' . $fileType; $filePath = $uploadDir . $fileName; if (file_put_contents($filePath, $decodedImage)) { // Tentukan URL absolut / relatif untuk disimpan di database // Sesuaikan dengan domain server hosting Anda $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $domain = $_SERVER['HTTP_HOST']; // Menemukan relative path dari root domain ke folder uploads $scriptPath = dirname($_SERVER['SCRIPT_NAME']); // misal: "/api/nota" // Naik dua tingkat karena index.php berada di /api/nota sedangkan uploads di /uploads $projectPath = dirname(dirname($scriptPath)); $photoPath = $protocol . $domain . $projectPath . '/uploads/' . $fileName; } else { // Fallback jika gagal menulis file ke disk (misal izin folder bermasalah) error_log("Gagal menyimpan file foto ke " . $filePath); } } // 7. Koneksi & Penyimpanan ke Database MySQL menggunakan PDO // SILAHKAN SESUAIKAN KREDENSIAL HOSTING ANDA DI BAWAH INI: $dbHost = 'localhost'; $dbName = 'irhammy1_motoris_db'; $dbUser = 'irhammy1_irhammy1'; $dbPass = 'sYAHLAeRZAN1302'; try { $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false ]); // Query prepared statement untuk menyisipkan laporan $sql = "INSERT INTO `laporan_nota` (`tanggal`, `wilayah`, `depo`, `nama_toko`, `kode_toko`, `nama_motoris`, `kode_da`, `ecg`, `omset_rupiah`, `report_text`, `photo_path`) VALUES (:tanggal, :wilayah, :depo, :nama_toko, :kode_toko, :nama_motoris, :kode_da, :ecg, :omset_rupiah, :report_text, :photo_path)"; $stmt = $pdo->prepare($sql); $stmt->execute([ ':tanggal' => $tanggal, ':wilayah' => $wilayah, ':depo' => $depo, ':nama_toko' => $namaToko, ':kode_toko' => $kodeToko, ':nama_motoris' => $namaMotoris, ':kode_da' => $kodeDa, ':ecg' => $ecg, ':omset_rupiah' => $omsetRupiah, ':report_text' => $reportText, ':photo_path' => $photoPath ]); // Kirim respons sukses http_response_code(201); echo json_encode([ "status" => "success", "message" => "Laporan penjualan motoris berhasil disimpan ke hosting database!", "data" => [ "id" => $pdo->lastInsertId(), "photo_url" => $photoPath, "tanggal" => $tanggal, "nama_toko" => $namaToko ] ]); } catch (PDOException $e) { // Log kesalahan teknis secara internal error_log("Database Error: " . $e->getMessage()); http_response_code(500); echo json_encode([ "status" => "error", "message" => "Gagal menyimpan laporan ke database server.", "debug" => $e->getMessage() // Sembunyikan ini di produksi demi keamanan eksternal ]); }