Files
2026-06-13 11:24:58 +07:00

111 lines
4.1 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* api/foto.php — Upload & kelola foto kondisi rumah (KF-13).
*
* GET ?warga_id=ID → daftar foto {id, url}
* POST multipart: warga_id + foto[] (15) → kompres & simpan
* DELETE ?id=ID → hapus foto
*
* Foto dikompres (maks lebar 1024px, JPEG q75) memakai GD.
*/
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/../config/app.php';
require_once __DIR__ . '/../config/activity.php';
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
// GET: cukup login. Mutasi: operator atau enumerator.
if ($method !== 'GET') requireApiAnyRole(['operator', 'enumerator']);
const MAX_FOTO = 5;
const UPLOAD_DIR = __DIR__ . '/../uploads/rumah/';
function compressImage(string $src, string $dst, int $maxW = 1024, int $quality = 75): bool {
$info = @getimagesize($src);
if (!$info) return false;
[$w, $h] = $info;
switch ($info['mime']) {
case 'image/jpeg': $img = imagecreatefromjpeg($src); break;
case 'image/png': $img = imagecreatefrompng($src); break;
case 'image/webp': $img = imagecreatefromwebp($src); break;
default: return false;
}
if (!$img) return false;
$nw = $w > $maxW ? $maxW : $w;
$nh = (int)round($h * ($nw / $w));
$canvas = imagecreatetruecolor($nw, $nh);
// latar putih untuk PNG transparan
imagefill($canvas, 0, 0, imagecolorallocate($canvas, 255, 255, 255));
imagecopyresampled($canvas, $img, 0, 0, 0, 0, $nw, $nh, $w, $h);
$ok = imagejpeg($canvas, $dst, $quality);
imagedestroy($img);
imagedestroy($canvas);
return $ok;
}
switch ($method) {
case 'GET':
$wargaId = $_GET['warga_id'] ?? null;
if (!$wargaId) sendError('warga_id wajib');
$stmt = $pdo->prepare("SELECT id, file_path FROM foto_rumah WHERE warga_id=? ORDER BY id");
$stmt->execute([$wargaId]);
$out = [];
while ($r = $stmt->fetch()) {
$out[] = ['id' => (int)$r['id'], 'url' => app_url($r['file_path'])];
}
sendSuccess($out, 'Foto rumah');
break;
case 'POST':
$wargaId = $_POST['warga_id'] ?? null;
if (!$wargaId) sendError('warga_id wajib');
if (empty($_FILES['foto'])) sendError('Tidak ada file diunggah');
$existing = (int)$pdo->query("SELECT COUNT(*) FROM foto_rumah WHERE warga_id=" . (int)$wargaId)->fetchColumn();
// Normalisasi $_FILES['foto'] ke array
$files = $_FILES['foto'];
$names = is_array($files['name']) ? $files['name'] : [$files['name']];
$tmps = is_array($files['tmp_name']) ? $files['tmp_name'] : [$files['tmp_name']];
if (!is_dir(UPLOAD_DIR)) mkdir(UPLOAD_DIR, 0775, true);
$saved = 0;
foreach ($tmps as $i => $tmp) {
if ($existing + $saved >= MAX_FOTO) break;
if (!is_uploaded_file($tmp)) continue;
$fname = 'w' . (int)$wargaId . '_' . uniqid() . '.jpg';
$dst = UPLOAD_DIR . $fname;
if (compressImage($tmp, $dst)) {
$rel = 'uploads/rumah/' . $fname;
$pdo->prepare("INSERT INTO foto_rumah (warga_id, file_path) VALUES (?,?)")
->execute([$wargaId, $rel]);
$saved++;
}
}
if ($saved === 0) sendError('Gagal memproses foto (format harus JPG/PNG/WEBP)');
logActivity($pdo, 'create', 'foto_rumah', (int)$wargaId, "Upload {$saved} foto");
sendSuccess(['uploaded' => $saved], "{$saved} foto diunggah", 201);
break;
case 'DELETE':
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID wajib');
$row = $pdo->prepare("SELECT file_path FROM foto_rumah WHERE id=?");
$row->execute([$id]);
$fp = $row->fetchColumn();
if ($fp) {
$abs = __DIR__ . '/../' . $fp;
if (is_file($abs)) @unlink($abs);
$pdo->prepare("DELETE FROM foto_rumah WHERE id=?")->execute([$id]);
logActivity($pdo, 'delete', 'foto_rumah', (int)$id, 'Hapus foto');
}
sendSuccess(null, 'Foto dihapus');
break;
default:
sendError('Method not allowed', 405);
}