id; // La cartella upload รจ public/user/document/. Questo file sta in public/api/, // quindi saliamo di un livello. $uploadDir = __DIR__ . '/../user/document/'; $allowedExt = ['pdf', 'jpg', 'jpeg', 'png']; $allowedMime = ['application/pdf', 'image/jpeg', 'image/png']; $maxBytes = 16 * 1024 * 1024; // 16 MB // ========================================================================== // INPUT // ========================================================================== $documentName = trim($_POST['document_name'] ?? ''); $expiryDate = trim($_POST['expiry_date'] ?? ''); if ($documentName === '') { $documentName = 'Certificato Medico'; } if ($expiryDate === '') { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Data di scadenza obbligatoria.']); exit; } // Validazione formato data YYYY-MM-DD $d = DateTime::createFromFormat('Y-m-d', $expiryDate); if ($d === false || $d->format('Y-m-d') !== $expiryDate) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Formato data non valido (YYYY-MM-DD).']); exit; } // File if (!isset($_FILES['certificate']) || $_FILES['certificate']['error'] !== UPLOAD_ERR_OK) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Nessun file ricevuto o errore upload.']); exit; } $file = $_FILES['certificate']; if ($file['size'] > $maxBytes) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Il file supera i 16 MB.']); exit; } $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); $finfo = new finfo(FILEINFO_MIME_TYPE); $realMime = $finfo->file($file['tmp_name']); if (!in_array($ext, $allowedExt, true) || !in_array($realMime, $allowedMime, true)) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'Formato non consentito. Usa PDF, JPG o PNG.']); exit; } // ========================================================================== // SALVATAGGIO FILE // ========================================================================== if (!is_dir($uploadDir)) { @mkdir($uploadDir, 0755, true); } $safeName = bin2hex(random_bytes(16)) . '.' . $ext; $destination = $uploadDir . $safeName; if (!move_uploaded_file($file['tmp_name'], $destination)) { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Salvataggio del file non riuscito.']); exit; } // ========================================================================== // INSERT DB // ========================================================================== try { $sql = "INSERT INTO certificateuserprofile (iduser, documentdescription, filenamedocument, expirydatedocument, uploaded_at) VALUES (:iduser, :descr, :fname, :expiry, :uploaded)"; $stmt = $db->prepare($sql); $stmt->execute([ ':iduser' => $userId, ':descr' => $documentName, ':fname' => $safeName, ':expiry' => $expiryDate, ':uploaded' => date('Y-m-d'), ]); $newId = (int) $db->lastInsertId(); } catch (Throwable $e) { // rollback file se l'insert fallisce @unlink($destination); http_response_code(500); echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio del documento.']); exit; } // ========================================================================== // OUTPUT // ========================================================================== echo json_encode([ 'success' => true, 'message' => 'Documento caricato correttamente.', 'certificate' => [ 'id' => $newId, 'document_name' => $documentName, 'filename' => $safeName, 'uploaded_at' => date('Y-m-d'), 'expiry_date' => $expiryDate, 'is_expired' => false, 'file_url' => '/user/document/' . $safeName, ], ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);