First commit / commit pertama

This commit is contained in:
Mr.Haruna
2026-06-13 11:24:58 +07:00
commit 522c4f7200
166 changed files with 13326 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
<?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);
}